Heim > System-Tutorial > LINUX > Nginx-Link-Tracking für Microservice-Architektur

Nginx-Link-Tracking für Microservice-Architektur

王林
Freigeben: 2024-08-06 16:34:49
Original
817 Leute haben es durchsucht

Nginx-Link-Tracking für Microservice-Architektur

In den meisten Microservice-Architekturen ist Nginx im Grunde eine häufig verwendete Zugriffsschichtfunktion, daher hoffen wir, dass die Anforderungs-ID überprüft und von der Nginx-Schicht ausgefüllt und im Nginx-Anforderungsprotokoll gedruckt wird.

Lesetipps: Dieser Artikel bietet keine vollständige Lösung für die Linkverfolgung, sondern lediglich eine Supportlösung für die Linkverfolgung auf der Nginx-Ebene!

1 Hintergrundeinführung

Die Geburt von Microservices hat viele Probleme traditioneller monolithischer Anwendungen gelöst, wie z. B. schlechte Wartbarkeit, schlechte Skalierbarkeit und schlechte Flexibilität (grobkörniger Vergleich). Obwohl die Microservice-Architektur gut ist, bringt sie auch viele Herausforderungen mit sich, von denen „Fehlerbehebung“ eine der Herausforderungen ist, die gelöst werden müssen. Wie finden Sie also die Grundursache eines Fehlers in vielen Anwendungen und Instanzen? Basierend auf den oben genannten Anforderungen können wir alle Protokolle, die von jeder Transaktion in jeder Anwendung generiert werden, zentral sammeln und anzeigen (jedoch nur, wenn Sie über Folgendes verfügen:

Log Center

). So können Sie schnell erkennen, bei welchem ​​Schritt die Transaktion fehlgeschlagen ist. Bei guter Durchführung können Sie auch direkt eine Sekundärentwicklung und Datenanalyse durchführen. Nach der Analyse der gesammelten Protokolle und Fehler können diese intuitiv mit einer grafischen Oberfläche angezeigt werden. Sie können beispielsweise das Topologiediagramm von Microservice-Aufrufen anzeigen und Farben verwenden, um Fehler zu unterscheiden (z. B. häufig verwendetes Rot: weist auf eine Anomalie hin, grün: normal, gelb: Warnung). Anschließend können Sie häufige Fehler oder Ausnahmen klassifizieren und eine benutzerfreundliche Anzeige erstellen (um es ganz klar auszudrücken: Es besteht keine Notwendigkeit, direkt zum Stapel zu gehen), z. B.: NullPointerException: Die Schnittstelle fordert direkt und benutzerfreundlich auf, welche Codezeile einen Nullzeiger ausgelöst hat und der Eingabeparameter ist What... (Dies ist nicht der Schwerpunkt dieses Artikels, daher werde ich nicht auf allzu viel Unsinn eingehen. Ich werde ihn später bei Gelegenheit ausführlich vorstellen.)

Um die Linkverfolgung der gesamten Microservice-Architektur durchzuführen, hoffen wir auf jeden Fall, dass es eine globale Transaktions-ID gibt, um alle Protokolle vom ersten Punkt an zuzuordnen, an dem eine Transaktion das Microservice-Center betritt (für die Linkverfolgung reicht eine solche ID definitiv nicht aus). aber nur dies wird hier vorgestellt). Am idealsten ist es natürlich, die Front-End-Protokolle (z. B. Betriebsprotokolle, Datenflüsse usw.) zu planen.

2 Nginx
In den meisten Microservice-Architekturen ist Nginx im Grunde eine häufig verwendete Zugriffsschichteinrichtung, daher hoffen wir, dass die Anforderungs-ID überprüft und von der Nginx-Schicht ausgefüllt und im Nginx-Anforderungsprotokoll gedruckt wird. Hier sind nur drei Möglichkeiten, die Transaktions-ID-Erstellungsmethode der Nginx-Schicht zu implementieren.

2.1 Option 2: Spleißen basierend auf integrierten Variablen In Versionen vor 1.11.0 können wir Splicing verwenden, um die Anforderungs-ID zusammenzustellen. Die Referenzkonfiguration ist wie folgt:
<span class="hljs-section">server</span> {
    <span class="hljs-comment"># 定义$request_trace_id的值,在1.11.0之前,我们可以使用类似的方式声明</span>
    <span class="hljs-comment"># 只要能确保其值出现重复的可能性尽可能的小即可。 </span>
    <span class="hljs-attribute">set</span> <span class="hljs-variable">$request_trace_id</span> trace-id-<span class="hljs-variable">$pid</span>-<span class="hljs-variable">$connection</span>-<span class="hljs-variable">$bytes_sent</span>-<span class="hljs-variable">$msec</span>;
    <span class="hljs-attribute">location</span> / {
        <span class="hljs-comment"># ……</span>
        <span class="hljs-comment"># 将此trace_id传递给后端的server,通过header方式,此后我们既可以在环境中获取此header  </span>
        <span class="hljs-attribute">proxy_set_header</span> X-Request-Id <span class="hljs-variable">$request_trace_id</span>;  
    }
}
Nach dem Login kopieren

Parameterbeschreibung

:

    $pid
  • : Nginx-Worker-Prozess-ID
  • $connection
  • : Die Anzahl der Link-IDs zum Upstream-Server
  • $bytes_sent
  • : Anzahl der gesendeten Bytes
  • $msec
  • : Die aktuelle Zeit, d. h. die von dieser Variablen erhaltene Zeit, einschließlich Sekunden und Millisekunden (geteilt durch .)
2.2 Option 3: Implementierung basierend auf LUA-Skript Verwenden Sie die zufällige
UUID

, die vom System /dev/urandom generiert wird. Das Referenzskript lautet wie folgt:

<span class="hljs-comment">---</span>
 <span class="hljs-comment">--- UUID</span>
 <span class="hljs-comment">--- Created by lry.</span>
 <span class="hljs-comment">--- DateTime: 2018/2/25 下午7:38</span>
 <span class="hljs-comment">--- Describe: 用系统/dev/urandom生成的随机uuid</span>
 <span class="hljs-comment">---</span>
 <span class="hljs-keyword">local</span> template =<span class="hljs-string">"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"</span>
 <span class="hljs-keyword">local</span> d = <span class="hljs-built_in">io</span>.open(<span class="hljs-string">"/dev/urandom"</span>, <span class="hljs-string">"r"</span>):read(<span class="hljs-number">4</span>)
 <span class="hljs-built_in">math</span>.randomseed(<span class="hljs-built_in">os</span>.time() + d:byte(<span class="hljs-number">1</span>) + (d:byte(<span class="hljs-number">2</span>) * <span class="hljs-number">256</span>) + (d:byte(<span class="hljs-number">3</span>) * <span class="hljs-number">65536</span>) + (d:byte(<span class="hljs-number">4</span>) * <span class="hljs-number">4294967296</span>))
<span class="hljs-keyword">local</span> uuid=<span class="hljs-built_in">string</span>.gsub(template, <span class="hljs-string">"x"</span>,
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(c)</span></span>
    <span class="hljs-keyword">local</span> v = (c == <span class="hljs-string">"x"</span>) <span class="hljs-keyword">and</span> <span class="hljs-built_in">math</span>.random(<span class="hljs-number">0</span>, <span class="hljs-number">0xf</span>) <span class="hljs-keyword">or</span> <span class="hljs-built_in">math</span>.random(<span class="hljs-number">8</span>, <span class="hljs-number">0xb</span>)
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">string</span>.format(<span class="hljs-string">"%x"</span>, v)
  <span class="hljs-keyword">end</span>)
<span class="hljs-keyword">return</span> uuid
Nach dem Login kopieren

2.3 Lösung 1: Basierend auf der $request_id-Implementierung

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>
Nach dem Login kopieren
3 最佳实践

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

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

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

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

Das obige ist der detaillierte Inhalt vonNginx-Link-Tracking für Microservice-Architektur. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:linuxprobe.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage