Background

NGINX 是一个通用且流行的应用程序。也是最流行的 Web 服务器,它可用于提供静态文件内容,但也通常与其他服务一起用作分布式系统中的组件,在其中它用作反向代理、负载均衡 或 API 网关。

分布式追踪 distributed tracing 是一种可用于分析与监控应用程序的机制,将追踪在从源到目的的整个过程中的单个请求,这与仅通过单个应用程序域来追踪请求的形式不同。

换句话说,我们可以说分布式追踪是对跨多个系统的多个请求的拼接。拼接通常由一个或多个相关 ID 完成,并且跟踪通常是一组记录的、跨所有系统的结构化日志事件,存储在一个中心位置。

在这种背景的情况下, OpenTracing 应运而生。OpenTracing 是一个与应用供应商无关的 API,它可帮助开发人员轻松地跟踪单一请求的域。目前有多种开源产品都支持 OpenTracing(例如,Jaeger, skywalking 等),并将其作为一种检测分布式追踪的标准化方法。

本文将围绕,从0到1实现在nginx配置分布式追踪的架构的简单实例说明。本文实例使用的组件为

  • nginx v1.22
  • jaeger-all-in-on v1.38
  • nginx-opentracing v1.22
  • jaeger-client-cpp v0.9

源码构建nginx-opentracing

准备nginx-opentracing

nginx-opentracing 仓库中可以看到,官方为每个nginx版本都提供了一个编译好的动态库(Nginx1.19.13+),我们可以直接拿来使用这个动态库,如果你想将这个利用Nginx 提供的编译参数 --add-module=/path/to/module 构建为nginx的内置功能的话,可能会出现一些问题,例如下面的一些错误:

ngx_http_opentracing_module.so/config was found
 /root/nginx-opentracing-0.25.0/opentracing//src/ngx_http_opentracing_module.cpp
In file included from /root/nginx-opentracing-0.25.0/opentracing//src/ngx_http_opentracing_module.cpp:1:0:
/root/nginx-opentracing-0.25.0/opentracing//src/load_tracer.h:3:38: fatal error: opentracing/dynamic_load.h: No such file or directory

根据 issue 中查询得知 nginx-opentracing 需要嵌入到nginx中,是需要一些 opentracing-cpp 因为对c++不熟,尝试调试很久还是上面的错误,故直接使用了官方提供的动态库。

准备jaeger-client-cpp

根据 nginx-opentracing 中提到的,还需要一个 jaeger-client-cpp 的 tracer 才可以正常运行(这也是作为jaeger架构中的角色)

来到 jaeger-client-cpp 看到Release提供的编译好的动态库已经很久了,而最新版都没有提供相应编译的版本,需要我们自己编译

说明: 编译依赖CMake 3.3+,gcc 4.9.2+

我们的编译环境使用CentOS 7 默认gcc与CMake都符合要求需要自行编译两个的版本。

编译gcc

gcc下载地址:https://ftp.gnu.org/gnu/gcc/

cd gcc-5.4.0
./contrib/download_prerequisitesmkdir gcc-build-5.4.0
cd gcc-build-5.4.0/usr/local/src/gcc-5.4.0/configure \--enable-checking=release \--enable-languages=c,c++ \--disable-multilibmake && make install

引用处理 refer 1

cd /usr/bin/
mv gcc gcc_back
mv g++ g++_back
ln -s /usr/local/bin/gcc gcc
ln -s /usr/local/bin/g++ g++

编译时遇到几个问题

/lib64/libstdc++.so.6: version GLIBCXX_3.4.20' not found

gcc 编译,libgcc动态库有改动,恢复原状即可

configure: error: C++ compiler missing or inoperationalmake[2]: \*** [configure-stage1-libcpp] Error 1
make[2]: Leaving directory `/home/clay/programming/C++/gcc-4.8.1'
make[1]: \*** [stage1-bubble] Error 2
make[1]: Leaving directory `/home/clay/programming/C++/gcc-4.8.1'
make: \*** [all] Error 2

编译cmake

./configure --prefix=/path/to/appmake
make install

这里遇到一个小问题 编译过程中遇到 [libstdc++.so.6: version GLIBCXX_3.4.20 not found

因为这里使用了自己编译的gcc版本,需要指定下动态库的路径 refer 2

LD_LIBRARY_PATH=/usr/local/lib64 ./configure --prefix=/usr/local/cmake

编译jaeger-client-cpp

这里根据官方提供的步骤操作即可

cd jaeger-client-cpp-0.9.0/
mkdir build
cd build
# 这里建议使用下科学上网,编译过程中会使用Hunter自动下载所需的依赖项
ALL_PROXY=http://x.0.0.x:10811 /usr/local/cmake/bin/cmake ..
make

注:依赖项挺大的,下载时间可能很长,会hang主,只需等待结束即可

​ 编译完成后 libjaegertracing.so.0.9.0 则是我们需要的

编译nginx

./configure \--user=web_www \--group=web_www \--with-pcre \--with-compat \--with-http_ssl_module  \--with-http_gzip_static_module \--prefix=/root/nginx  \--with-http_stub_status_module

--with-compat 必须加上,表面允许使用动态库,否则编译完在启动时会报下面的错误

nginx: [emerg] module "/root/nginx/conf/ngx_http_opentracing_module.so" is not binary compatible in /root/nginx/conf/nginx.conf:1

遇到的问题,cc nou found,这里只需将 gcc 软连接一份为 cc 即可

配置nginx

准备jaeger-client的配置

jaeger.json,参数的说明可以参考configuration

{"service_name": "nginx", // 服务名"sampler": {"type": "const","param": 1},"reporter": {"localAgentHostPort": "jaeger:6831" // jaeger agent的地址},"headers": { // jaeger的默认的jaeger Baggage头设置"jaegerDebugHeader": "jaeger-debug-id","jaegerBaggageHeader": "jaeger-baggage","traceBaggageHeaderPrefix": "uberctx-"},"baggage_restrictions": {"denyBaggageOnInitializationFailure": false,"hostPort": ""}
}

在nginx中开启opentracing

对于 nginx-opentracing 更多的参数可以参考 Reference.md

# 加载 OpenTracing 动态模块。
load_module conf/ngx_http_opentracing_module.so;
worker_processes  1;
user root root;events {worker_connections  1024;
}
http {log_format opentracing '{"timestamp":"$time_iso8601",''"source":"$server_addr",''"hostname":"$hostname",''"ip":"$http_x_forwarded_for",''"traceID":"$opentracing_context_uber_trace_id",''"client":"$remote_addr",''"request_method":"$request_method",''"scheme":"$scheme",''"domain":"$server_name",''"referer":"$http_referer",''"request":"$request_uri",''"args":"$args",''"size":$body_bytes_sent,''"status": $status,''"responsetime":$request_time,''"upstreamtime":"$upstream_response_time",''"upstreamaddr":"$upstream_addr",''"http_user_agent":"$http_user_agent",''"https":"$https"''}';# 加载 tracer,这里使用的jaeger,需要传递配置文件opentracing_load_tracer conf/libjaegertracing.so conf/jaeger.json;# 启用 tracing opentracing on; # 设置tag,可选参数opentracing_tag http_user_agent $http_user_agent;include       mime.types;default_type  application/octet-stream;sendfile        on;keepalive_timeout  65;server {listen       80;server_name  localhost;location / {opentracing_operation_name $uri;opentracing_propagate_context;root   html;index  index.html index.htm;}access_log logs/access.log opentracing;error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}}
}

注:这里使用的 opentracing-nginx 的动态库为 ot16 ,linux-amd64-nginx-1.22.0-ot16-ngx_http_module.so.tgz ,另外一个版本不兼容,-t 检查语法时会提示

配置说明

对于每一个location都可以对其设置别名,这个就是 opentracing_operation_nameopentracing_location_operation_name 的区别

http {
...location = /upload/animal {opentracing_location_operation_name upload;...

更多的配置说明可以参考 Tutorial.md

此时我们可以在jaeger上查看,可以看到 NGINX 的 span(因为这里只配置了NGINX,没有配置更多的后端)。

Reference

1 CentOS7 升级 GCC 到 5.4.0 版本

2 libstdc++.so.6: version GLIBCXX_3.4.20 not found

3 nginx load_module

让你的nginx支持分布式追踪opentracing相关推荐

  1. 开放分布式追踪(OpenTracing)入门与 Jaeger 实现

    摘要: 分布式系统的运维挑战 容器.Serverless 编程方式的诞生极大提升了软件交付与部署的效率.在架构的演化过程中,可以看到两个变化: 应用架构开始从单体系统逐步转变为微服务,其中的业务逻辑随 ...

  2. OpenTracing开放式分布式追踪规范说明介绍整理

    一.OpenTracing:开放式分布式追踪规范 两个组成部分 Trace:调用链,追踪链路,由span组成. Span:跨度点,一次跨方法调用 span属性 Operation name:操作名词 ...

  3. 【学习笔记】分布式追踪Tracing

    在软件工程中,Tracing指使用特定的日志记录程序的执行信息,与之相近的还有两个概念,它们分别是Logging和Metrics. Logging:用于记录离散的事件,包含程序执行到某一点或某一阶段的 ...

  4. 分布式追踪系统Jaeger

    前言 随着公司的发展,业务不断增加,模块不断拆分,系统间业务调用变得越复杂,对定位线上故障带来很大困难.整个调用链不透明,犹如系统被蒙上一块黑纱,当线上遇到故障时,整个技术部就陷入痛苦的漩涡.这时候分 ...

  5. 40张图看懂分布式追踪系统原理及实践

    前言 在微服务架构中,一次请求往往涉及到多个模块,多个中间件,多台机器的相互协作才能完成.这一系列调用请求中,有些是串行的,有些是并行的,那么如何确定这个请求背后调用了哪些应用,哪些模块,哪些节点及调 ...

  6. 传递给系统调用的数据区域太小怎么解决_40张图看懂分布式追踪系统原理及实践...

    作 者:码海 原文链接:https://mp.weixin.qq.com/s/U-8ttlVCfYtjEPOWKBHONA 前言 在微服务架构中,一次请求往往涉及到多个模块,多个中间件,多台机器的相互 ...

  7. 从Zipkin到Jaeger,Uber的分布式追踪之道tchannel

    uber 的 tchannel 的模式是更优雅的实现模式 从Zipkin到Jaeger,Uber的分布式追踪之道 作者|Yuri Shauro 编辑|大愚若智 对于希望监视复杂的微服务架构系统的组织, ...

  8. ASP.NET Core使用Jaeger实现分布式追踪

    前言 最近我们公司的部分.NET Core的项目接入了Jaeger,也算是稍微完善了一下.NET团队的技术栈. 至于为什么选择Jaeger而不是Skywalking,这个问题我只能回答,大佬们说了算. ...

  9. 传递给系统调用的数据区域太小怎么解决_一口气说出“分布式追踪系统”原理!...

    " 在微服务架构中,一次请求往往涉及到多个模块,多个中间件,多台机器的相互协作才能完成. 图片来自 Pexels 这一系列调用请求中,有些是串行的,有些是并行的,那么如何确定这个请求背后调用 ...

最新文章

  1. 爬虫python需要什么软件-python的爬虫流程是什么?这是编程小白必须要了解的
  2. Windows Phone中Wallet钱包的使用
  3. rails3系统架构
  4. autosar网络管理_AP AUTOSAR平台设计(11)——网络管理
  5. linux解锁文件.user.ini,Linux下解决网页服务器权限和.user.ini无法删除的问题
  6. Spring-AbstractRefreshableApplicationContext
  7. 6.Python学习笔记:[enumerate元素加序号;isdigit()像数字;len()计算长度]
  8. nginx实现动态分离,解决css和js等图片加载问题
  9. keras TimeDistributed 描述
  10. SPOJ-LCS Longest Common Substring
  11. VSTO 学习笔记(六)在 Excel 2010中使用RDLC报表
  12. 史上最全jquery视频教程
  13. 【NodeJS】Codecademy学习笔记
  14. 848. Shifting Letters**
  15. Markdown整理备忘(一)-- 符号整理
  16. linux svn 查看忽略文件,SVN忽略文件或文件夹几种方法总结linux操作系统 -电脑资料...
  17. Python Selenium爬虫实现歌曲免费下载
  18. 锦州铁路高中2021高考成绩查询入口,锦州高考成绩查询系统
  19. scikit-learn中评估分类器性能的度量,像混淆矩阵、ROC、AUC等
  20. 2022国际版多语言多商户智能机器人在线客服源码配置文档

热门文章

  1. SDWebImage 第三方框架的使用——网络图片的处理操作
  2. excel中vlookup函数的使用方法_Excel教程:函数VLOOKUP实用技巧
  3. python学习(五)--打印错误信息
  4. css里的英文翻译,css常见英文翻译
  5. python中shelf对象_shelve 用来持久化任意的Python对象实例代码_python_脚本之家
  6. google退出后产生的影响
  7. c语言如何宏定义枚举型结构体,C语言学习笔记--枚举结构体
  8. Git 的暂存区(staging area)理解
  9. Android开发使用Glide获取图片背景色淡绿色解决办法
  10. chrome 自动加载ajax.googleapis,使用Redirector插件解决googleapis公共库加载的问题