>  기사  >  시스템 튜토리얼  >  마이크로서비스 아키텍처를 위한 Nginx 링크 추적

마이크로서비스 아키텍처를 위한 Nginx 링크 추적

王林
王林원래의
2024-08-06 16:34:49735검색

마이크로서비스 아키텍처를 위한 Nginx 링크 추적

대부분의 마이크로서비스 아키텍처에서 Nginx는 기본적으로 일반적으로 사용되는 액세스 계층 기능이므로 요청 ID가 Nginx 계층에서 확인 및 채워지고 Nginx 요청 로그에 인쇄되기를 바랍니다.

읽기 팁: 이 기사는 링크 추적을 위한 완전한 솔루션을 제공하지 않고 Nginx 계층에서 링크 추적을 위한 지원 솔루션만 제공합니다!

1 배경 소개

마이크로서비스의 탄생은 낮은 유지 관리성, 낮은 확장성, 낮은 유연성(대략적인 비교) 등 기존 모놀리식 애플리케이션의 많은 문제를 해결했습니다. 마이크로서비스 아키텍처는 훌륭하지만 많은 과제도 안겨줍니다. 그중 문제 해결은 해결해야 할 과제 중 하나입니다. 그렇다면 여러 애플리케이션과 인스턴스에서 오류의 근본 원인을 어떻게 찾을 수 있을까요?

위 요구 사항을 기반으로 각 애플리케이션의 각 거래에서 생성된 모든 로그를 중앙에서 수집하고 표시할 수 있습니다(단, 로그 센터가 있는 경우에만 해당). 이렇게 하면 거래가 실패한 단계를 빠르게 확인할 수 있습니다. 잘 수행되었다면 수집된 로그와 장애를 분석한 후 2차 개발 및 데이터 분석을 직접 수행할 수도 있으며 그래픽 인터페이스를 통해 직관적으로 표시할 수도 있습니다.

예를 들어, 마이크로서비스 호출의 토폴로지 다이어그램을 표시하고 색상을 사용하여 오류를 구분할 수 있습니다(예: 일반적으로 사용되는 빨간색: 이상을 나타냄, 녹색: 정상, 노란색: 경고). 그런 다음 일반적인 오류나 예외를 분류하고 다음과 같이 친숙한 표시를 할 수 있습니다(직접적으로 스택으로 이동할 필요가 없음). NullPointerException: 인터페이스는 어떤 코드 줄이 null 포인터를 던졌는지 직접적이고 친숙한 프롬프트를 표시합니다. , 입력 매개변수는 무엇입니까...(이 글의 초점은 이 부분이 아니므로 너무 장황한 내용은 다루지 않겠습니다. 나중에 기회가 되면 자세히 소개하겠습니다.)

전체 마이크로서비스 아키텍처의 링크 추적을 수행하려면 트랜잭션이 마이크로서비스 센터에 진입하는 첫 번째 지점부터 모든 로그를 연결하는 글로벌 트랜잭션 ID가 있기를 바랍니다(링크 추적의 경우 이러한 ID로는 충분하지 않습니다. 그러나 여기서는 이것만 소개합니다). 물론 가장 이상적인 것은 프런트 엔드 로그(예: 작업 로그, 데이터 흐름 등)를 계획하는 것입니다.

2 Nginx

대부분의 마이크로서비스 아키텍처에서 Nginx는 기본적으로 일반적으로 사용되는 액세스 계층 기능이므로 요청 ID가 Nginx 계층에서 확인 및 채워지고 Nginx 요청 로그에 인쇄되기를 바랍니다. Nginx 레이어의 트랜잭션 ID 생성 방법을 구현하는 방법은 세 가지뿐입니다.

2.1 옵션 2: 내장 변수를 기반으로 접합

1.11.0 이전 버전에서는 스플라이싱을 사용하여 요청 ID를 조합할 수 있습니다. 참조 구성은 다음과 같습니다.

으아악

매개변수 설명:

  • $pid: nginx 작업자 프로세스 ID
  • $connection: 업스트림 서버에 대한 링크 ID 수
  • $bytes_sent: 보낸 바이트 수
  • $msec: 현재 시간, 즉 초와 밀리초를 포함하여 이 변수로 얻은 시간( .)
2.2 옵션 3: LUA 스크립트를 기반으로 구현

시스템 /dev/urandom에서 생성된 무작위 UUID를 사용하세요. 참조 스크립트는 다음과 같습니다.

으아악
2.3 솔루션 1: $request_id 구현 기반

Nginx在 1.11.0版本中就提供了内置变量 $request_id ,其原理就是生成32位的随机字符串,虽不能比拟UUID的概率,但32位的随机字符串的重复概率也是微不足道了,所以一般可视为UUID来使用即可。参考配置如下:

<span class="hljs-comment"># Nnginx代理默认会把header中参数的 "_" 下划线去掉,所以后台服务器后就获取不到带"_"线的参数名</span>
<span class="hljs-attribute">underscores_<span class="hljs-keyword">in</span>_headers</span> <span class="hljs-literal">on</span>;

<span class="hljs-comment"># 设定日志格式</span>
<span class="hljs-attribute"><span class="hljs-built_in">log</span>_format</span> main  \<span class="hljs-string">'<span class="hljs-variable">$remote_addr</span> - <span class="hljs-variable">$remote_user</span> [<span class="hljs-variable">$time_local</span>] "<span class="hljs-variable">$request</span>" \'
                 \'<span class="hljs-variable">$status</span> <span class="hljs-variable">$body_bytes_sent</span> "<span class="hljs-variable">$http_referer</span>" <span class="hljs-variable">$upstream_http_request_id</span> \'
                 \'"<span class="hljs-variable">$http_user_agent</span>" "<span class="hljs-variable">$http_x_forwarded_for</span>"\';

server {
    location / {
        <span class="hljs-comment"># 如果请求头中已有该参数,则获取即可;如果没有,则使用</span><span class="hljs-variable"><span class="hljs-comment">$request_id</span></span><span class="hljs-comment">进行填充</span>
        <span class="hljs-built_in">set</span> <span class="hljs-variable">$temp_request_id</span> <span class="hljs-variable">$http_x_request_id</span>;
        <span class="hljs-keyword">if</span> (<span class="hljs-variable">$temp_request_id</span> = "") {
            <span class="hljs-built_in">set</span> <span class="hljs-variable">$temp_request_id</span> <span class="hljs-variable">$request_id</span>;
        }
        <span class="hljs-comment"># 屏蔽掉原来的请求头参数</span>
        proxy_<span class="hljs-built_in">set</span>_header  x_request_id        "";
        <span class="hljs-comment"># 设置向后转发的请求头参数</span>
        proxy_<span class="hljs-built_in">set</span>_header  X-Request-Id        <span class="hljs-variable">$temp_request_id</span>;
    }
}
</span>
3 最佳实践

生成交易ID的方式有很多种,但希望使用者结合自身实际情况进行合理取舍,而不要盲目的追求ID的唯一性、可读性和时序性等等。

比如,ID具有时序性虽然有一定的好处,但实际的架构根本没有去使用该时序性,则没必要花大量的精力和做出大量的开发,去实现一个有时序性的交易ID。又比如,觉得UUID可读性太差,从而花了很多成本去开发一个具有一定含义的交易ID(如前几位表示什么意思,多少位到多少位又表示什么意思之类的),开发出来后,实际架构根本没有去解读该ID的地方,则浪费了成本。

但也不是所有人都直接使用UUID就能满足的,比如我需要考虑日志的容量,则可以考虑适当缩减ID的长度(每个ID缩减10个字符串,每笔交易就可能少几百或几千个字符串,再往上规划,还是可以减少一些日志容量的)。

最后,如果有考虑想收集前端的日志的童鞋,建议交易ID就不要使用Long型,因为前端可能会有损失精度的问题。同时也建议使用 $request_id  来填充交易ID。

위 내용은 마이크로서비스 아키텍처를 위한 Nginx 링크 추적의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.