logid让你的请求完整可追溯
今天是在博客园开园的第一天
一时间其实并不能想起来到底该写什么文章,其实想写的东西挺多
今天就以logid这个主题开始吧,网上写这个的文章似乎不多,但是的确是在实际生产中相当重要的一个能力,也是容易被大多数新手程序员所忽视的。
logid:在我的定义里,logid是一个能够代表一条请求唯一性的字段。完整请求包含请求到达、请求转发、服务处理、数据存取等多个阶段,logid在其中充当的就是一个定位标识,当然这个字段叫法可能不能可以是traceID或者其他XXID等等
以典型的php服务为例,整条请求轨迹可能包含下面的几个组成部分:
client => 外层网关(四层负载均衡) => nginx集群(七层负载均衡) => 你自己服务的nginx => 业务日志 => rpc日志 => mysqlproxy => mysql
=> redisproxy => redis
=> 其他基础服务(图片服务\评论服务等等)
上面展示的是一个比较完善的请求转发路径,而这样的长路径上,任何一个位置都可能产生问题。大部分情况下,每个阶段也都会打日志
如何把这些日志串联起来、让问题可追溯、请求可定位,这便是logid做的事情。
典型的使用场景例如:
案例一:业务可用性出现问题,如何排查问题出在哪里?
假设你自己的服务机器nginx出现了大量的499报错,499错误源于客户端主动断开连接。
那么问题可能处在哪里?
- 客户端的超时时间设置有问题,太短了(这个原因引起的499错误,只存在于上新服务。如果服务存在很久了,这个原因基本可以忽略)
- 客户端和你之前的网络故障,这也是一个常见的引起因素。(这个问题的定位可以把nginx_proc_time和upstream_time都打出来即可辨别)
- 极大的可能问题出在你的服务请求别人或者自己的机器负载过高导致的
今天主要讨论第三种,如何定位?
关键是看这条请求从nginx => pfm => php执行 => rpc请求这些过程哪些步骤出现了问题
没有logid的时候你怎么做?
nginx找到问题日志,根据get参数或者post参数去业务日志找,请求少的还好,如果大量重复请求呢?你是没办法精确定位到一个请求的
并且大部分rpc的日志不会打get参数,我们的rpc日志每秒百条,所以需要有一个线索,穿起来
logid就是扮演这个角色
nginx把请求上游的logid通过fastcgi带给php,php通过$SERVER中取到,然后rpc框架和php代码约定好从哪里取logid
done!下次再来问题,直接一步定位,不需要肉身来定位了
案例二: sql问题反查业务日志
假设某天DBA找到你说Proxy日志发现了大量的sql存在注入风险,并且抛给你一堆sql、来源IP和时间
一般如何处理?找到来源ip机器、找到对应时间的日志、翻译sql中的关键字到你的日志关键字(人肉),这个步骤如果没法对应起来,可能很困难
但是如果你们约定好了sql发出去的时候带上logid字段,这个情况是不是迎刃而解?你只需要grep相应的logid便可以找到对应的,效率也会高很多
如何在发sql请求带上logid?可以使用类似下面的sql语句,proxy完成sql日志打印
/*logid=xxx*/select count(1) from tableA
当然还有很多案例
logid存在的核心价值是让每一个请求都可以被唯一定位!
具体logid的协议如何定制需要具体问题具体分析,但是意识上在遇到类似问题的时候应该想到,你的服务需要在日志中打印线索ID:logid来让你的每一个请求可以被定位
当然前提是log打的充分、也要恰当
logid让你的请求完整可追溯的更多相关文章
- ASP.NET Core获取请求完整的Url
在ASP.NET项目中获取请求完整的Url: 获取System.Web命名空间下的类名为HttpRequestBase的Url方法: /// <summary>在派生类中替代时,获取有关当 ...
- 95秀-异步http请求完整过程
最终调用时的代码 private void ansyClearApplyInfor() { RequestParams params = new RequestParams() ...
- HTTP深入浅出 http请求完整过程
HTTP(HyperText Transfer Protocol)是一套计算机通过网络进行通信的规则.计算机专家设计出HTTP,使HTTP客户(如Web浏览器)能够从HTTP服务器(Web服务器)请求 ...
- java拦截器获取请求完整参数
public class OptLogAspect implements HandlerInterceptor { @Override public boolean preHandle(HttpSer ...
- MOOC(7)- case依赖、读取json配置文件进行多个接口请求-完整的测试类,含依赖测试(15)
ddt.依赖测试.断言.测试数据写回 # -*- coding: utf-8 -*- # @Time : 2020/2/12 23:07 # @File : test_class_15.py # @A ...
- java如何得到GET和POST请求URL和参数列表(转)
在servlet中GET请求可以通过HttpServletRequest的getRequestURL方法和getQueryString()得到完整的请求路径和请求所有参数列表,POST的需要getPa ...
- java如何得到GET和POST请求URL和参数列表
转载:http://blog.csdn.net/yaerfeng/article/details/18942739 在servlet中GET请求可以通过HttpServletRequest的getRe ...
- servlet获得完整路径
request.getQueryString() request.getParameterMap() request.getParameterNames() 在servlet中GET请求可以通过Htt ...
- JavaEE:response响应和request请求
Web服务器接收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象.request和response对象既然代表请求和响应,那么我 ...
随机推荐
- Codeforces 869E. The Untended Antiquity (二维Fenwick,Hash)
Codeforces 869E. The Untended Antiquity 题意: 在一张mxn的格子纸上,进行q次操作: 1,指定一个矩形将它用栅栏围起来. 2,撤掉一个已有的栅栏. 3,询问指 ...
- Java终止线程的三种方式
停止一个线程通常意味着在线程处理任务完成之前停掉正在做的操作,也就是放弃当前的操作. 在 Java 中有以下 3 种方法可以终止正在运行的线程: 使用退出标志,使线程正常退出,也就是当 run() 方 ...
- 微信小程序之状态管理A
其实这个标题 不是很对 主要是最近小程序项目中 有这么一个状态 所有商品都共用一个商品详情页面 大概就是这样子 为了公司 保险起见,一些展示的内容已经处理 但是无伤大雅 就是这么两个按钮 左侧粉色 ...
- Oracle Database的基本概念
一个 Oracle 服务器:是一个关系数据库管理系统(RDBMS),它提供全面的, 近乎完整的信息管理由Oracle 实例和Oracle 数据库组成Oracle 数据库 和 Oracle 实例Orac ...
- document.onselectstart=function(){return false;} 引起的拖动问题
在网页中拖动时,会引起某些文字或一些内容被选中,导致网页中蓝蓝的一片,视觉效果很差,所以我加了个1.document.onselectstart=function(){return false;}或者 ...
- chrome调试笔记
F12启动调试 1.右键加载按钮可以清空缓存并重新加载,有时候浏览器有缓存,代码更新不会及时反映出来. 2.performance mointer实时查看performance 点击三个竖着的小点,选 ...
- 数据中心网络架构的问题与演进 — 混合云与 VPC 专有网络
目录 文章目录 目录 前文列表 历史背景 混合云 Why hybrid cloud? 混合云市场 混合云的逻辑架构 混合云应用场景 灾难恢复 数据备份 负载扩容 应用部署 开发测试生产部署 混合云产品 ...
- 一百二十:CMS系统之注册功能前后端逻辑
给提交按钮加一个id,方便写js js //发送ajax请求注册请求$(function () { $('#submit-btn').click(function (event) { event.pr ...
- kubernetes架构(2)
一.Kubernetes 架构: Kubernetes Cluster 由 Master 和 Node 组成,节点上运行着若干 Kubernetes 服务. Master 节点 Master 是 Ku ...
- java数据结构之LinkedHashMap
一.LinkedHashMap源码注释 public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map& ...