dubbo流量上线时的非平滑问题

云小蜜 Dubbo3.0 实践:从微服务迁移上云到流量治理 简介:阿里云-达摩院-云小蜜对话机器人产品基于深度机器学习技术、自然语言理解技术和对话管理技术,为企业提供多引擎、多渠道、多模态的对话机器人服务。17 年云小蜜对话机器人在公共云开始公测,同期在混合云场景也不断拓展。为了同时保证公共云、混合云发版效率和稳定性,权衡再三我们采用了 1-2 个月一个大版本迭代。 前言 阿里云-达摩院-云小蜜对话机器人产品基于深度机器学习技术、自然语言理解技术和对话管理技术,为企业提供多引擎、多渠道、多模态的对话机器人服务。17 年云小蜜对话机器人在公共云开始公测,同期在混合 阅读详情

前言

笔者最近解决了一个困扰了业务系统很久的问题。这个问题只在发布时出现,每次只影响一两次调用,相较于其它的问题来说,这个问题有点不够受重视。由于种种原因,使得这个问题到了业务必须解决的程度,于是就到了笔者的手上。

问题现场

我们采用的是dubbo服务,这是个稳定成熟的RPC框架。但是我们在某些应用中会发现,只要这个应用一发布(或者重启),就会出现请求超时的问题,如下图所示:
在这里插入图片描述
而且都是第一笔请求会报错,之后就再也没有问题了。

排查日志

好了,现象我们知道了,于是开始排查那个时间点的日志。Server端没有任何日志,而Client(App1)端报错超时。报错如下所示:

2019-08-22 20:33:50.798
com.alibaba.dubbo.rpc.RpcException:
	Failed to invoke the method set in the servce XXXFacade,
	tries 1 times
	......
	start time: 2019-08-22 20:32:50.474
	end time: 2019-08-22 30:33:50.767 
	timeout=60000,channel:/21.64.21.164:44502->21.64.35.75:20880

看日志报错是这个tcp五元组(21.64.21.164:44502->21.64.35.75:20880)有问题。于是笔者netstat了一下,查看当前此连接的状态:

netstat -anp | grep 44502
21.64.21.164:44502 21.64.35.75:20880 ESTABLISHED

这个连接处于正常的ESTABLISHED状态,而且调用21.64.35.75这个server的连接只有这一个,那后续这台机器调用21.64.35.75这个server肯定只用到了这个连接,查看日志发现除了这一笔,其它调用一切正常。

思路1:Server端处理超时

按照上面的报错,肯定这个连接有问题,按照正常思路,是否是第一笔调用的时候各种初始化过程(以及jit)导致server处理请求过慢?如下图所示:
在这里插入图片描述
但这个问题很快被第二笔请求(和第一笔请求间隔只有一秒)给否决了。也就是说第一笔请求花了60s还超时,而第二笔请求在第一笔请求发出后的一秒后发出就成功了(而且耗时是毫秒级的)。如果按照上述思路,第二笔请求也应该等各种初始化完成之后再处理,也应该卡相当长的一段时间才对。再加上server端没有任何日志,就感觉好像没有收到请求。

思路2:Client端没有发送成功

于是我们开始了思路2,Client端没有发送成功。由于Dubbo是基于Netty的,其请求传输的处理过程是个NIO的异步化过程(只不过通过使用future机制对业务来说是同步的)。首先我们看下dubbo的超时检测机制,如下图所示:
在这里插入图片描述
当然,还有future的超时机制,这边我就不列举出来了。从这个机制可以看出,就算Client端发送的时候(因为写是写到socket的writebuffer里面,一般不会满,所以不会报错)没有发送出去,也不会在发的那一刻报出错误,而是要等定时扫描。为了验证这个猜想,笔者就开始着手排查连接的日志。

连接日志

因为规律是第一笔失败,那么笔者开始怀疑连接创建的有问题,但后面的请求成功又表明连接创建是没有问题的。那么,是否是连接还没有创建好就发送了第一笔请求呢?带着这样的疑问,笔者找到了如下的日志:

2019-08-22 20:32:51.876 (DubboClientReconnectTimer-thread-1) Successed connect to server /21.64.35.75:20880 ... channel is 
NettyChannel /21.64.21.164:44502 => /21.64.35.75:20880

由日志所示,21.64.21.164:44502这个连接串是在2019-08-22 20:32:51.876连接成功的,而上面出错的日志起始时间为

请求发送时间:2019-08-22 20:32:50.474
连接开始建立时间:2019-08-22 20:32:51.876
连接成功建立时间:2019-08-22 20:32:51.876

请求在连接成功建立之前,感觉非常符合笔者上述的猜想。但细想又不对,上述日志表示的是在2019-08-22 20:32:51.876开始建立连接并在1ms内建立成功连接。而请求确是50s发出的,dubbo本身代码不可能在连接还没做出创建动作的时候就开始发送请求(因为44502是由kernel分配的,没到创建连接动作之前是不可能知道这个端口号的,但它却在日志里面打印出来了),如下图所示:
在这里插入图片描述
思考了一段时间,笔者觉得这种情况很有可能是日志是不准确的,它仅仅打印当前连接包装类中的信息,之前那个出错的连接已经被新建的连接掩盖了(在日志中)。我们看下dubbo中对应的打印日志代码:

    private String getTimeoutMessage(boolean scan) {
        long nowTimestamp = System.currentTimeMillis();
        return (sent > 0 ? "Waiting server-side response timeout" : "Sending request timeout in client-side")
                + (scan ? " by scan timer" : "") + ". start time: "
                + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(start))) + ", end time: "
                + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date())) + ","
                + (sent > 0 ? " client elapsed: " + (sent - start)
                + " ms, server elapsed: " + (nowTimestamp - sent)
                : " elapsed: " + (nowTimestamp - start)) + " ms, timeout: "
                + timeout + " ms, request: " + request + ", channel: " + channel.getLocalAddress()
                + " -> " + channel.getRemoteAddress();
    }

这个21.64.21.164:44502是由channel.getLocalAddress()得出的,我们看下调用链:

channel.getLocalAddress()
	|->nettyClient.channel.getLocalAddress()

笔者看了下代码,dubbo在reconnect(重新连接的时候)会把nettyClient.channel换掉,从而可能打印出来和发送请求时不同的client端口信息。再加上日志里面打印出来的线程号DubboClientReconnectTimer-thread-1就几乎可以确定,之前还有一个连接,只不过这个连接失败了,新建的连接为21.64.21.164:44502。再仔细的找了下日志,发现了下面这条日志:

------------------日志分割线----------------
2019-08-22 20:32:51,876(DubboClientReconnectTimer-thread-1)  Close old Netty channel /21.64.21.164:44471 :> 21.64.35.75:20880
on create new netty channel /21.64.21.164:44502 => /21.64.35.75:20880
------------------日志分割线----------------
2019-08-22 20:32:51.876 (DubboClientReconnectTimer-thread-1) Successed connect to server /21.64.35.75:20880 ... channel is 
NettyChannel /21.64.21.164:44502 => /21.64.35.75:20880

即是说dubbo在把21.64.21.164:44471关闭后,立马创建了21.64.21.164:44502 那么整体过程如下图所示:
在这里插入图片描述
我们看下21.64.21.164:44471是什么时候创建的,继续搜寻日志:

zgrep '21.64.21.164:44471' dubbo.log.1.zip
2019-08-22 20:31:59.871 (ZkClient-EventThread-23) Successed connect to server /21.64.35.75:20880 ... channel is 
NettyChannel /21.64.21.164: 44471 => /21.64.35.75:20880
------------------日志分割线----------------
2019-08-22 20:32:51,876(DubboClientReconnectTimer-thread-1)  Close old Netty channel /21.64.21.164:44471 :> 21.64.35.75:20880

发现其在

连接1创建时间:2019-08-22 20:31:59.871
请求发送时间:2019-08-22 20:32:50.474
连接1关闭时间:2019-08-22 20:32:51,876

而且笔者翻看了业务日志,发现连接1在其生命周期内有且只有一笔请求,这笔请求就是报错的请求,由此可以看出这个连接1从建立成功开始就无法使用。

为什么连接建立成功确无法使用

首先由于dubbo是基于netty的,这种成熟的广泛应用的框架在创建连接这种问题上不应该会有问题。 而笔者仔细翻看netty翻看netty源码也确实遵守了NIO的编写套路。那么问题可能出现在环境上,既然应用(client/server)本身日志找不到更多的有用信息,那么看看操作系统能否有什么可以追寻的蛛丝马迹。于是笔者首先用dmesg查看下kernel打印的日志,client端没发现什么有用的信息,但server端的dmesg引起了笔者的注意

possible SYN flooding on port 20880. Sending cookies.
possible SYN flooding on port 20880. Sending cookies.
possible SYN flooding on port 20880. Sending cookies.
possible SYN flooding on port 20880. Sending cookies.
possible SYN flooding on port 20880. Sending cookies.

其字面意思为kenerl本身可能在20880端口遭到了SYN泛洪攻击,发送cookies。 这种日志会在并发连接过多的情况下由kernel打印出来。笔者netstat了下频繁出问题的机器,发现其特点都是连接特别多(达到了好几千甚至上万)。而dubbo的上线机制是只要注册到zookeeper后,zookeeper给所有的机器推送,所有的机器立马连接,这样就会造成比较高的并发连接,如下图所示:
在这里插入图片描述
既然怀疑到了高并发connect,那么笔者就立马用netstat看下kernel对于tcp的统计信息:

netstat -s
...
TcpExt:
	...
	1607 times the listen queue of a socket overflowed
	...

果然有这种并发连接导致的统计信息,socket overflowed表示的是server端的tcp_backlog队列溢出了。到这里笔者有八成把握是这个tcp_backlog设置的过小的问题了。下面就是分析,tcp_backlog溢出为什么会导致上述连接虽然成功但是第一笔报错的现象,从而和日志相印证,来证明笔者的猜测。

tcp_backlog溢出分析

tcp的三次握手
先从tcp的三次握手进行着手分析,从tcp_v4_do_rcv函数进行入手,因为这个函数是tcp协议获取packet的地方,当三次握手的SYN第一次进来的时候,应该会走这个函数:

// 先考察一下三次握手的第一个SYN
int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb){
	if (sk->sk_state == TCP_LISTEN) {
		......
		// 由于现在连接处于第一个SYN,现在server端的socket处于LISTEN状态
		struct sock *nsk = tcp_v4_hnd_req(sk, skb);
		......
	}
}
// 我们继续看下tcp_v4_hnd_req代码,三次握手第一个SYN kernel走的分支
tcp_v4_do_rcv
	/* 由于tcp_v4_hnd_req没有发现和此五元组对应的连接,所以do nothing */
	|->tcp_v4_hnd_req
	|->tcp_rcv_state_process
			/** case TCP_LISTEN && th->syn */
			|->conn_request(tcp_v4_conn_request)

我们继续分析conn_request函数,由于里面很多逻辑,所以我们滤掉了很多细节:

int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) {
	// 如果csk的reqsk queue满了,则设置want_cookie标识
	if (inet_csk_reqsk_queue_is_full(sk) && !isn) {
		if (sysctl_tcp_syncookies) {
			want_cookie = 1;
		}
		......
		if(want_cookie){
			// 下面这行就是打印possible SYN flooding的地方
			syn_flood_warning(skb);
			......
		}
		// 发送synack,即三次握手的第二次握手
		// 注意want_cookie的时候并不把对应的req加入到reqsk的hash列表中
		if (__tcp_v4_send_synack(sk, req, dst) || want_cookie)
			goto drop_and_free;
		// 如果发送syack成功,则加到hash列表里面
		inet_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
		......
		drop_and_free;
			reqsk_free(req);
		return 0;
	}
}

上面就是三次握手的前两次握手,如下图所示:
在这里插入图片描述
现在让我们看下最关键的第三次握手(客户端发给server ack的过程),依旧从tcp_v4_do_rcv开始

tcp_v4_hnd_req
	|->tcp_v4_hnd_req
// 这里面分两种情况
static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb){
	// 首先从inet_csk_search_req看是否有对应的五元组
	struct request_sock *req = inet_csk_search_req(sk, &prev, th->source,
						       iph->saddr, iph->daddr);
	// 这边的req分支下的tcp_check_req是重点,我们下面再分析
	if (req)
		return tcp_check_req(sk, skb, req, prev);
	// 处理established情况
	// 如果inet_csk没找到,则可能是需要syn cookie,处理syn cookie
	// 下面这条语句应该是在syn
	sk = cookie_v4_check(sk, skb, &(IPCB(skb)->opt));
	// 如果处理成功,则把其加入到inet_csk_reqsk_queue_add队列中
	......					     
}

上面这些代码片段主要表明的就是如果三次握手成功,会在server端把新创建的server端sock放到inet_csk_reqsk里面,然后由后面的tcp_child_process去处理。
在这里插入图片描述
tcp_check_req

上面分析完大致的tcp三次握手代码逻辑之后,我们现在看看造成本文问题现象的核心分支tcp_check_req,这个是在对应的req被放到inet_csk_reqsk(即不需要cookie或者cookie校验成功)后才能执行到这一句,源码如下:

// 下边是client ack回来后的处理过程
// 笔者为了简单起见,我们省略cookie校验的逻辑
struct sock *tcp_check_req(......){
	/* 各种处理,各种校验 */
	child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, 	NULL);
	// 如果syn_recv_sock返回空,则跳到listen_overflow
	if (child == NULL)
		goto listen_overflow;
	......
listen_overflow:
	// 如果没有设置tcp_abort_on_overflow则设置acked=1
	if (!sysctl_tcp_abort_on_overflow) {
		inet_rsk(req)->acked = 1;
		return NULL;
	}}
	// 增加内核统计参数
	NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_EMBRYONICRSTS);
	// 如果设置了tcp_abort_on_overflow则发送reset报文
	if (!(flg & TCP_FLAG_RST))
		req->rsk_ops->send_reset(sk, skb);
	// 同时将当前sock从csk_reqsk中删除,即当client端下次报文过来的时候,无法找到
	// 对应的csk_reqsk
	inet_csk_reqsk_queue_drop(sk, req, prev);
	return NULL;

如果进了listen_overflow分支,server端会有两种现象,一个是直接将acked设置为1(仅设置标识不发送ack),另一个是发送ack。这两个分支都会把对应的req从reqsk_queue中删除。下图就是走了listen_overflow后不同分之,三次握手的情况:

不设置tcp_abort_on_overflow
在这里插入图片描述
设置tcp_abort_on_overflow

在这里插入图片描述
由上面看出设置了tcp_abort_on_overflow会在三次握手之后立马置为closed状态,二不设置tcp_abort_on_overflow会等第一个请求发出来的时候才会知道这个连接其实已经被server端丢弃了。

什么时候listen_overflow

看上面的代码,即在syn_recv_sock返回null的时候,会到listen_overflow,对应的tcp协议的函数为:

struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
				  struct request_sock *req,
				  struct dst_entry *dst){
		....
		if (sk_acceptq_is_full(sk))
			goto exit_overflow;
		......
}

sk_acceptq_is_full里面判断full的队列长度是下面这三个参数中的最小值:

取三者中的最小值
/proc/sys/inet/ipv4/tcp_max_syn_backlog
/proc/sys/net/core/somaxconn
tcp listen函数调用时候传入的back_log

限于篇幅,就不给出这里判断队列是否为full的源码了。

修复方案

设置kernel参数
一开始笔者仅仅在server端设置了下面这三个参数(天真的以为dubbo考虑到了backlog,设置了一个较大的数值,其实其用了jdk默认的50)

注意,这边511是根据redis的建议值设置的
/proc/sys/inet/ipv4/tcp_max_syn_backlog 511
/proc/sys/net/core/somaxconn 511
/proc/sys/net/ipv4/tcp_abort_on_overflow 1

发现依旧有Close old netty client这样的错误日志,但是业务方确告诉笔者已经没有上线流量损失的情况了。笔者上去观察了一下情况,发现没有流量损失是由于如上图所述reset报文立马发回来,导致能够出错的时间窗口缩小为2s,而不是之前的第一笔必报错,2s内由于没有任何请求,所以大大减少了出错概率。如下图所示:
在这里插入图片描述
而创建连接和close old netty client日志的间隔都是小于等于两秒也证明了tcp_abort_on_overflow生效了

dubbo代码增加backlog的设置

由于dubbo用的是jdk默认的backlog(50),所以笔者在dubbo源码对应的部分做了调整,如下代码所示:

public class NettyServer extends AbstractServer implements Server {
	......
	protected void doOpen() throws Throwable {
		...
		// 可以从jvm参数中动态调整这个backlog
		String backlog = System.getProperty(BACK_LOG_KEY);
		if(StringUtils.isEmpty(backlog)){
			// 默认为2048,这边调大点,反正改内核参数是即时生效的
			backlog = DEFAULT_BACK_LOG;
		}
		bootstrap.setOption("backlog",backlog);
		......
	}
}

将这个修改过的dubbo版本给业务方(server端)用了以后,再也没有对应的报错日志了,dubbo上线也平滑了。

总结

事实上,从开始分析问题到猜测要调整backlog所花费的时间并不长。但是笔者喜欢把所有的细节和自己的猜想一一印证,通过源码分析出来的过程图景能够将所有的问题现象全部解释,是一件很爽快的事情。

文章来源:https://my.oschina.net/alchemystar/blog/3098219

推荐阅读:https://www.roncoo.com/view/54

DP链路训练从HPD触发到通道对齐:原理与调试实战 高速数字接口的稳定工作依赖物理层信号的精确协商,链路训练正是DisplayPort接口中确保源端与接收端在速率、摆幅和时序上达成一致的关键机制。HPD作为链路状态变化的触发信号,与通道对齐一同构成了训练流程的首尾环节。理解从时钟恢复到均衡再到多通道对齐的完整过程,有助于快速定位显示异常问题。在工程实践中,借助DPCD寄存器交互和AUX通道日志,可以系统性地排查训练失败原因。围绕链路训练全流程进行剖析,重点探讨HPD触发机制、训练图案选择、寄存器配置以及链路降级策略,为显示方案开发与调试提供工程参考。 阅读详情

相关推荐

(3万字深度解析)Kaggle《房价预测:高级回归技巧》详解复现攻略

在这篇教程式文章中,我们从零开始完成了 Kaggle《房价预测:高级回归技巧》比赛的复现工作,涵盖了数据预处理、特征工程、模型训练、调优、解释和融合的完整流程。深入理解数据:阅读数据描述,结合常识对每个特征作出合理处理(如缺失值填充’None’表示无此设施 、异常值剔除 等)。对目标和偏态特征进行对数变换,使分布更平滑,从而更好满足模型假设并提升准确度。特征工程:我们创造了总面积、总浴室等新特征,整合信息提高模型可学习性。

qq_38334677的博客 1776

Dubbo源码分析 之 netty调用获取返回值

netty作为异步非阻塞的rpc框架,也是dubbo默认的远程rpc协议,让我们来看一下dubbo的客户端是实现同步获取返回信息的效果的: 在调用发送请求之前,如果我们设置断点进行跟踪的话会进入一连串的Invoker ,因为在dubbo客户端只有接口没有具体的实现类,所以dubbo使用反向代理的方式实现类方法的代理调用,最终会进入 DubboInvoker 类的 doInvoke 方法:

rewerma的博客 4289

聊一聊固态电池和钠离子电池新技术

总之,固态电池是一种“安全又高效的未来电池”,它的好处非常明显,但目前还处于研发阶段,离普及还有一段距离。未来,这两种技术可能会与锂离子电池并存,分别满足不同的市场需求。我尝试用最通俗易懂的语言将复杂的技术讲给大家听。钠离子电池和锂离子电池的工作原理很相似,但它用的是。固态电池和钠离子电池是两种正在研发和推广的。,它们有潜力解决现有锂离子电池的部分缺点。,而不是锂(Li)。

weixin_33324696的博客 3334

解Bug之路-dubbo流量上线时的非平滑问题

前言 笔者最近解决了一个困扰了业务系统很久的问题。这个问题只在发布时出现,每次只影响一两次调用,相较于其它的问题来说,这个问题有点不够受重视。由于种种原因,使得这个问题到了业务必须解决的程度,于是就到了笔者的手上。 问题现场 我们采用的是dubbo服务,这是个稳定成熟的RPC框架。但是我们在某...

chenpoxian8496的博客 501

SAR成像系列:【9】合成孔径雷达(SAR)成像算法-波数域(omega-K)成像算法[也叫距离徙动(RM)算法](附Matlab代码)

合成孔径雷达(SAR)波数域(wK)成像算法也称为距离徙动(RM)算法,它不存在近似条件,可以对整个成像区域基于散射点模型进行精确聚焦。有的文章中称它为SAR成像的最佳实现。

zr2006_7的专栏 1万+

在微信小程序中如何引入iconfont

略

sayyy的专栏 4327

JVM调优实战:to-space exhausted & Evacuation Failure

一次线上dubbo问题的定位,进行JVM调优实战。

yzh_1346983557的博客 3312

Python爬虫教程:微博热点话题抓取与社交媒体分析

微博是中国最大的社交媒体平台之一,拥有海量的用户和丰富的讨论话题。通过爬取微博的热门话题和讨论内容,我们可以深入分析用户的兴趣、舆论走势、社会情绪等。通过爬取微博的热点话题和讨论内容,我们可以获得关于当前热门话题的宝贵数据,并基于这些数据进行多种社交媒体分析。本文将通过Python爬虫技术,详细介绍如何抓取微博上的热门话题、话题讨论内容,并进行社交媒体分析。希望本文为你提供了一个全面的微博数据抓取与分析的指南,帮助你在社交媒体数据分析的道路上迈出坚实的第一步。微博上的一些页面内容是静态的,可以直接通过。

2201_76125261的博客 591

Dubbo的两种调用模式和超时异常

先推荐大家阅读dubbo官网源码解读服务调用流程一节,传送门: dubbo.apache.org/zh-cn/docs/… 一、调用模式 Dubbo同步调用还是异步调用的逻辑是在DubboInvoker中,Dubbo 实现同步和异步调用比较关键的一点就在于由谁调用 ResponseFuture 的 get方法。 同步调用模式下,由框架自身调用 ResponseFuture 的 get 方法。 异...

weixin_34315485的博客 2012

python利用IQR方法与3σ方法进行异常值处理(含代码)

python利用IQR方法进行异常值处理

weixin_46713695的博客 2031

测试用例设计工具大盘点:总有一款适合你

本文旨在帮助测试工程师、开发人员及团队管理者快速了解主流测试用例设计工具的特点、适用场景和选择逻辑。覆盖工具类型包括传统文档工具、开源管理工具、商业集成平台及新兴AI工具,范围涵盖中小团队到大型企业的不同需求。本文从“测试用例设计的痛点”切入,用生活案例解释核心概念;接着按“工具类型”分类盘点主流工具(附优缺点对比表);再通过“小团队/中大型团队/敏捷团队”等真实场景教你选工具;最后展望AI等未来趋势,帮你“一次学透,终身受用”。

项目管理的博客 1593

Dubbo超时生效原理以及服务端配置推送

Dubbo目录1. Dubbo超时参数是设置1.1 一般的超时时间1.2 timeoutCountDown2. 服务端怎么到客户端的merge配置到客户端的代码3. 超时之后的异常是从哪里出来的1. dubbo的超时参数是从那设置的1.1 一般的超时时间1.2 timeoutCountDown2. 服务端怎么到客户端的merge配置到客户端的代码3. 超时之后的异常是从哪里出来的 Dubbo 客户端超时设置是Dubbo 客户端参数最常用设置参数。本文介绍了超时参数的配置方式,超时异常的相关排查和Dubbo里

1269

在 SAP BTP ABAP Environment 里把 ATC 跑成流水线:定时检查 + 告警邮件,一次打通

摘要 本文介绍了如何在SAP BTP ABAP环境中实现ATC检查的自动化流程。通过将ATC与质量体系结合,构建从检查到通知的完整闭环:使用Custom Code Analysis Project定义检查范围,通过Application Jobs实现定时调度,利用标准CDS View读取结果,最后开发通知作业发送告警邮件。文章重点阐述了云环境下不同于On-Premise的实现思路,包括Test Variant设计、作业编排模板应用等关键环节,并提供了可落地的代码示例。这种自动化方案能有效解决人工检查的滞后性

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 170

dubbo日志关闭_dubbo流量上线时的非平滑问题

点击上方蓝色字关注我们~前言笔者最近解决了一个困扰了业务系统很久的问题。这个问题只在发布时出现,每次只影响一两次调用,相较于其它的问题来说,这个问题有点不够受重视。由于种种原因,使得这个问题到了业务必须解决的程度,于是就到了笔者的手上。问题现场我们采用的是dubbo服务,这是个稳定成熟的RPC框架。但是我们在某些应用中会发现,只要这个应用一发布(或者重启),就会出现请求超时的问题,如下图...

weixin_36187176的博客 187

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

dubbo日志关闭_解Bug之路-dubbo流量上线时的非平滑问题

前言笔者最近解决了一个困扰了业务系统很久的问题。这个问题只在发布时出现,每次只影响一两次调用,相较于其它的问题来说,这个问题有点不够受重视。由于种种原因,使得这个问题到了业务必须解决的程度,于是就到了笔者的手上。问题现场我们采用的是dubbo服务,这是个稳定成熟的RPC框架。但是我们在某些应用中会发现,只要这个应用一发布(或者重启),就会出现请求超时的问题,如下图所示: 而且都是第一笔请求会报错,...

weixin_42134537的博客 936

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

后发送过慢的问题_解Bug之路-dubbo流量上线时的非平滑问题

前言笔者最近解决了一个困扰了业务系统很久的问题。这个问题只在发布时出现,每次只影响一两次调用,相较于其它的问题来说,这个问题有点不够受重视。由于种种原因,使得这个问题到了业务必须解决的程度,于是就到了笔者的手上。问题现场我们采用的是dubbo服务,这是个稳定成熟的RPC框架。但是我们在某些应用中会发现,只要这个应用一发布(或者重启),就会出现请求超时的问题,如下图所示: 而且都是第一笔请求会报错,...

weixin_40001275的博客 235

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Dubbo :服务上线不影响旧版本的解密

服务上线时如何确保不影响旧版本是Dubbo微服务架构中的关键问题。本文从主管角度解析几种常见发布策略:灰度发布、蓝绿部署、Canary发布等,并结合实际场景分析其优缺点。通过合理的版本控制设计和兼容性优化,可以有效降低风险。文章还将探讨如何选择合适的策略,确保新旧版本平滑过渡,保障系统稳定性,提升用户体验。

蓝鲸鱼计算机软件开发工作室 442

Java-79 深入浅出 RPC Dubbo 动态路由架构详解:从规则设计到上线系统集成

Dubbo 路由规则是实现服务调用精细化控制的关键机制,支持基于标签、方法、参数、IP等维度进行服务筛选与转发。配置方式包括配置文件、注解和动态配置中心(如 Nacos、Zookeeper)。常见场景有灰度发布、流量隔离、故障规避等。在实践中,开发者可通过设置优雅下线、服务预热、延迟注册等手段,实现平滑的服务上线与滚动升级。此外,结合脚本路由与动态监听机制,可实现更强大的流量调度与多版本管理能力,大幅提升系统的稳定性与扩展性。

谢谢你的喜欢 我们一起无限进步 1250

Dubbo灰度发布完全指南:从精准引流到全链路灰度

Dubbo通过其成熟的标签路由参数路由和分组版本控制机制,为微服务架构下的灰度发布提供了从简单到复杂、从单点到全链路的完整解决方案。掌握这些能力,意味着你能够以零中断、可度量、可逆的方式,自信地将变更交付到生产环境,真正实现业务的敏捷与稳定并存。架构师视角:灰度发布不仅仅是一种技术,更是一种面向失败设计的工程文化。它标志着团队从“害怕变更”转向“拥抱并管理变更”,是通往高效能研发组织的重要一步。

全栈开发工程师 2379

Dubbo 服务上线怎么兼容旧版本?思维导图 代码示例(java 架构)

为了确保 Dubbo 服务在上线新版本时能够兼容旧版本,通常需要采取一系列措施来保证平滑过渡。这包括但不限于版本控制、接口设计的向后兼容性、使用默认值处理可选参数、提供降级策略等。以下是实现这些目标的具体方法和建议。

qq_33240556的博客 694

解决微服务架构下流量有损问题的实践和探索

简介:绝⼤多数的软件应⽤⽣产安全事故发⽣在应⽤上下线发布阶段,尽管通过遵守业界约定俗成的可灰度、可观测和可滚回的安全⽣产三板斧,可以最⼤限度的规避发布过程中由于应⽤⾃身代码问题对⽤户造成的影响。但对于⾼并发⼤流量情况下的短时间流量有损问题却仍然⽆法解决。因此,本文将围绕发布过程中如何解决流量有损问题实现应⽤发布过程中的⽆损上下线效果相关内容展开⽅案介绍。 ⽆损上下线背景 据统计,应⽤的事故⼤多发⽣在应⽤上下线过程中,有时是应⽤本身代码问题导致。但有时我们也会发现尽管代码本身没有问题,但在应⽤上下线发布.

q66562636的博客 514

中仑网络全站 Dubbo 2 迁移 Dubbo 3 总结

中仑网络在 2022 年完成了服务框架从 Dubbo 2 到 Dubbo 3 的全站升级,深度使用了应用级服务发现、Kubernetes 原生服务部署、服务治理等核心能力。

数据库技术 235
上一篇: 企业员工角色权限管理平台(SpringBoot2.0+Mybatis+Shiro+Vue)
下一篇: 从spring boot发邮件聊到开发的友好性
java_66666
博客等级 码龄10年 339粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值