0

0

微服务架构之Nginx链路追踪

WBOY

WBOY

发布时间:2024-08-06 22:22:12

|

792人浏览过

|

来源于Linux就该这么学

转载

微服务架构之nginx链路追踪

在大部分的微服务架构中,Nginx基本是常用的接入层设施,所以我们希望请求ID从Nginx层进行校验填充,并且打印在Nginx的请求日志中。

阅读提示:本文不提供链路追踪的完整解决方案,只提供Nginx层对链路追踪的支持方案!

1 背景介绍

微服务的诞生,解决了传统单体应用的很多问题,如可维护性差、扩展性差和灵活性差等问题(粗粒比较)。微服务架构虽好,但同时也带来了很多挑战,其中 故障排查 就是其需要解决的挑战之一。那么,如何在很多个应用和实例中找到故障发生的根源呢?

基于以上需求,我们可以将每一笔交易在各个应用中产生的所有日志,进行集中式收集与展示(但前提是你得有:日志中心)。这样就可以很快看出交易是在哪一步出的故障。如果做得好,还可以直接进行二次开发与数据分析,将收集的日志和出现的故障进行分析后,用图形界面很直观的进行展示。

比如,可以展示出微服务调用的拓扑图,使用颜色进行区分故障(如常用红:表示异常、绿:正常、黄:警告)。接着可以将常出现的故障或异常进行分类后做出友好型的展示(说白了就不用直接上堆栈),如:NullPointerException:则界面直接友好型的提示哪一行代码抛了空指针,输入参数是什么……(这不是该篇的重点哈,废话不多说了,后续有机会再详细介绍)。

要做整个微服务架构的链路追踪,肯定是希望从交易进入微服务中心的第一个点就开始有一个全局的交易ID来关联所有日志(链路追踪,这么一个ID肯定是不够的,但这里只介绍这个哈)。当然最理想的肯定是希望把前端的日志(如操作日志、数据流等)也规划进行。

2 Nginx

在大部分的微服务架构中,Nginx基本是常用的接入层设施,所以我们希望请求ID从Nginx层进行校验填充,并且打印在Nginx的请求日志中。这里只提供三种方式来实现Nginx层的交易ID生产方式。

2.1 方案二:基于内置变量拼接

在1.11.0之前的版本,我们可以采用拼接的方式来组装请求ID。参考配置如下:

红墨
红墨

一站式小红书图文生成器

下载
server {
    # 定义$request_trace_id的值,在1.11.0之前,我们可以使用类似的方式声明
    # 只要能确保其值出现重复的可能性尽可能的小即可。 
    set $request_trace_id trace-id-$pid-$connection-$bytes_sent-$msec;
    location / {
        # ……
        # 将此trace_id传递给后端的server,通过header方式,此后我们既可以在环境中获取此header  
        proxy_set_header X-Request-Id $request_trace_id;  
    }
}

参数说明

  • $pid:nginx worker进程号
  • $connection:与upstream server链接id数
  • $bytes_sent:发送字节数
  • $msec:当前时间,即此变量获取的时间,包含秒、毫秒数(中间以.分割)
2.2 方案三:基于LUA脚本实现

利用系统/dev/urandom 生成的随机 UUID 。参考脚本如下:

---
 --- UUID
 --- Created by lry.
 --- DateTime: 2018/2/25 下午7:38
 --- Describe: 用系统/dev/urandom生成的随机uuid
 ---
 local template ="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
 local d = io.open("/dev/urandom", "r"):read(4)
 math.randomseed(os.time() + d:byte(1) + (d:byte(2) * 256) + (d:byte(3) * 65536) + (d:byte(4) * 4294967296))
local uuid=string.gsub(template, "x",
  function (c)
    local v = (c == "x") and math.random(0, 0xf) or math.random(8, 0xb)
    return string.format("%x", v)
  end)
return uuid
2.3 方案一:基于  $request_id  实现

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

# Nnginx代理默认会把header中参数的 "_" 下划线去掉,所以后台服务器后就获取不到带"_"线的参数名
underscores_in_headers on;

# 设定日志格式
log_format main  \'$remote_addr - $remote_user [$time_local] "$request" \'
                 \'$status $body_bytes_sent "$http_referer" $upstream_http_request_id \'
                 \'"$http_user_agent" "$http_x_forwarded_for"\';

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

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

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

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

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

相关专题

更多
nginx 重启
nginx 重启

nginx重启对于网站的运维来说是非常重要的,根据不同的需求,可以选择简单重启、平滑重启或定时重启等方式。本专题为大家提供nginx重启的相关的文章、下载、课程内容,供大家免费下载体验。

227

2023.07.27

nginx 配置详解
nginx 配置详解

Nginx的配置是指设置和调整Nginx服务器的行为和功能的过程。通过配置文件,可以定义虚拟主机、HTTP请求处理、反向代理、缓存和负载均衡等功能。Nginx的配置语法简洁而强大,允许管理员根据自己的需要进行灵活的调整。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

490

2023.08.04

nginx配置详解
nginx配置详解

NGINX与其他服务类似,因为它具有以特定格式编写的基于文本的配置文件。本专题为大家提供nginx配置相关的文章,大家可以免费学习。

496

2023.08.04

tomcat和nginx有哪些区别
tomcat和nginx有哪些区别

tomcat和nginx的区别:1、应用领域;2、性能;3、功能;4、配置;5、安全性;6、扩展性;7、部署复杂性;8、社区支持;9、成本;10、日志管理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

222

2024.02.23

nginx报404怎么解决
nginx报404怎么解决

当访问 nginx 网页服务器时遇到 404 错误,表明服务器无法找到请求资源,可以通过以下步骤解决:1. 检查文件是否存在且路径正确;2. 检查文件权限并更改为 644 或 755;3. 检查 nginx 配置,确保根目录设置正确、没有冲突配置等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

329

2024.07.09

Nginx报404错误解决方法
Nginx报404错误解决方法

解决方法:只需要加上这段配置:try_files $uri $uri/ /index.html;即可。想了解更多Nginx的相关内容,可以阅读本专题下面的文章。

3505

2024.08.07

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

248

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

205

2023.09.04

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 6.3万人学习

Git 教程
Git 教程

共21课时 | 2.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号