Comments (20)
接收方的日志
INFO [tor-7-thread-12]
INFO [tor-7-thread-15]
INFO [tor-7-thread-19]
INFO [tor-7-thread-18]
INFO [utor-7-thread-1]
INFO [utor-7-thread-4]
INFO [utor-7-thread-1]
INFO [utor-7-thread-9]
INFO [utor-7-thread-8]
INFO [utor-7-thread-3]
INFO [tor-7-thread-10]
INFO [utor-7-thread-7]
会不会是接收时的线程不是同一个导致的,如果想调整,如何配置。
from sofa-bolt.
知道了,在 AbstractUserProcessor 实现类中重写 getExecutor() 方法;使用一个线程处理就可以得到正确的顺序了。
from sofa-bolt.
是的,时序要考虑清楚发送线程和处理线程的逻辑
from sofa-bolt.
请问下,接收方重写 getExecutor() 后,理论上可以保证顺序。但是现在接收到的顺序是乱的,在发送方还需要做什么设置吗。
... 省略部分代码
for (int i = 1; i <= 100; i++) {
StringValue ready1 = new StringValue();
ready1.value = "data == " + i;
rpcClient.oneway(connection, ready1);
}
from sofa-bolt.
client 用一个connection 顺序发送,服务端用一个线程处理应该是保证顺序的
抓包看下呢,看网络层数据是有序的吗?
from sofa-bolt.
client 用一个connection 顺序发送,服务端用一个线程处理应该是保证顺序的 抓包看下呢,看网络层数据是有序的吗?
还没抓包, #323 这里有个可复现的 demo
from sofa-bolt.
client 用一个connection 顺序发送,服务端用一个线程处理应该是保证顺序的 抓包看下呢,看网络层数据是有序的吗?
你好,这个bug能定位到问题吗?
from sofa-bolt.
@iohao 看了下你的demo, 你把验证是否乱序的逻辑写到了客户端的 Callback中, 我觉得这是个问题点.
我们整体看一次调用, 会涉及到三个线程池:
- 客户端发送的线程池
- 服务端处理的线程池
- 客户端处理回调的线程池
现在 客户端处理回调的线程池 出现了乱序, 我看了下,这个线程池是 org.java_websocket.client.WebSocketClient
控制的,并不能代表 2.服务端处理的线程池
出现了乱序.
from sofa-bolt.
@iohao 看了下你的demo, 你把验证是否乱序的逻辑写到了客户端的 Callback中, 我觉得这是个问题点.
我们整体看一次调用, 会涉及到三个线程池:
- 客户端发送的线程池
- 服务端处理的线程池
- 客户端处理回调的线程池
现在 客户端处理回调的线程池 出现了乱序, 我看了下,这个线程池是
org.java_websocket.client.WebSocketClient
控制的,并不能代表2.服务端处理的线程池
出现了乱序.
org.java_websocket.client.WebSocketClient
是指 DemoWebsocketClient 这个启动类吧,这个启动类的主要作用是为了触发请求。
也就是为了触发下面 DemoAction.order() 方法
@ActionController(1)
public class DemoAction {
@ActionMethod(3)
public void order() {
//
var broadcastContext = BrokerClientHelper.getBroadcastOrderContext();
CmdInfo cmdInfo = CmdInfo.getCmdInfo(1, 3);
for (int i = 1; i <= 100; i++) {
IntValue intValue = new IntValue();
intValue.value = i;
broadcastContext.broadcastOrder(cmdInfo, intValue);
}
}
}
broadcastContext.broadcastOrder(cmdInfo, intValue); 内部是调用的 rpcClient.oneway 方法,已经确定使用的是同一连接 channel 了。
此时的调用连链是:RpcClient -> RpcServer -> RpcClient -> DemoWebsocketClient
与之对应的调用处理代码点就是:
1 broadcastContext.broadcastOrder ->
2 BroadcastOrderMessageBrokerProcessor.java ->
3 BroadcastOrderMessageExternalProcessor.java ->
4 DemoWebsocketClient.java
所以,只需要看 2、3
这两个环节就可以了,
看下图的打印
以 - : 打头的是 BroadcastOrderMessageBrokerProcessor.java 打印的数据,分别打印的是:
- 30
- 31
- 32
以 local ------ : 打头的是 BroadcastOrderMessageExternalProcessor.java 打印的数据,分别打印的是:
local ------ : 29
local ------ : 32
local ------ : 30
所以,在还没有给到模拟客户端这个环节数据就乱了;BroadcastOrderMessageBrokerProcessor、BroadcastOrderMessageExternalProcessor 都是设置的单线程。
最后才到模拟客户端的类 DemoWebsocketClient.java
在 DemoWebsocketClient.java 的控制台中,打印的数据分别是:29、32、30
那么也就是说,从 BroadcastOrderMessageExternalProcessor 给到模拟客户端的数据是对得上的。
from sofa-bolt.
from sofa-bolt.
@iohao 看了下确实有你说的问题. 尝试调试了下,没查出问题. 现在 Client 和 Server 再一个 JVM 里面, 我打了断点很难确认是客户端逻辑还是服务端逻辑, 能不能提供一个 客户端和服务端分开启动的 Demo 呢?
from sofa-bolt.
@iohao 看了下确实有你说的问题. 尝试调试了下,没查出问题. 现在 Client 和 Server 再一个 JVM 里面, 我打了断点很难确认是客户端逻辑还是服务端逻辑, 能不能提供一个 客户端和服务端分开启动的 Demo 呢?
拉取一下 order 分支的代码 https://github.com/iohao/ioGameSimpleOne
.
├── DemoAction.java
├── DemoApplication.java
├── DemoLogicServer.java
├── DemoWebsocketClient.java
└── multiple
├── MyBrokerServerApp.java
├── MyExternalApp.java
└── MyLogicApp.java
新增了 MyBrokerServerApp、MyExternalApp、MyLogicApp 三个类,可以分别的单独启动。
启动顺序为
- MyBrokerServerApp
- MyExternalApp
- MyLogicApp
- DemoWebsocketClient
之后可以多启动几次 DemoWebsocketClient.java 发起请求来测试。
from sofa-bolt.
@iohao 找到原因了: RpcCommandHandler.handle 在处理批量请求的时候,会引入一个线程池,这个线程池导致了后续处理乱序.
加上这行代码关掉这个功能之后, 我测试就不乱序了:
System.setProperty(RpcConfigs.DISPATCH_MSG_LIST_IN_DEFAULT_EXECUTOR,"false");
from sofa-bolt.
@iohao 找到原因了: RpcCommandHandler.handle 在处理批量请求的时候,会引入一个线程池,这个线程池导致了后续处理乱序. 加上这行代码关掉这个功能之后, 我测试就不乱序了:
System.setProperty(RpcConfigs.DISPATCH_MSG_LIST_IN_DEFAULT_EXECUTOR,"false");
感谢!可以分享一下分析过程吗。
from sofa-bolt.
感谢!可以分享一下分析过程吗。
1.通过抓包和分析请求可以发现, 在 bolt 包 content 中 第 438, 349 (350) 两到三位字节代表 proto 中的那个int ,我们抓包, 日志都通过观察这三位.其中 438 固定是 8 , 439 从0 开始 以2 为 step 递增.
2. 一开始用 wireshark 抓包,想看看包是不是有序的. 看上去是有序的, 但实际上最后发现,包也是乱序的. 用wireshrk看还是不清晰.
3. 改动bolt Encoder , Decoder 代码,分别输出 线程号和 439位数据. 发现服务端 Decoder是顺序的, encoder 是乱序的.
4. debug 服务端处理代码, 发现在 userProcessor executor 的阻塞队列中的数据已经是乱序的了.
5. 在创建 com.alipay.remoting.rpc.protocol.RpcRequestProcessor.ProcessTask#ProcessTask 的时候打印 线程名称,发现有意料之外的线程名, debug 到这边,往上翻翻 stack 就看到 RpcCommandHandler 的代码了
@iohao
from sofa-bolt.
感谢!可以分享一下分析过程吗。
1.通过抓包和分析请求可以发现, 在 bolt 包 content 中 第 438, 349 (350) 两到三位字节代表 proto 中的那个int ,我们抓包, 日志都通过观察这三位.其中 438 固定是 8 , 439 从0 开始 以2 为 step 递增. 2. 一开始用 wireshark 抓包,想看看包是不是有序的. 看上去是有序的, 但实际上最后发现,包也是乱序的. 用wireshrk看还是不清晰. 3. 改动bolt Encoder , Decoder 代码,分别输出 线程号和 439位数据. 发现服务端 Decoder是顺序的, encoder 是乱序的. 4. debug 服务端处理代码, 发现在 userProcessor executor 的阻塞队列中的数据已经是乱序的了. 5. 在创建 com.alipay.remoting.rpc.protocol.RpcRequestProcessor.ProcessTask#ProcessTask 的时候打印 线程名称,发现有意料之外的线程名, debug 到这边,往上翻翻 stack 就看到 RpcCommandHandler 的代码了 @iohao
谢谢分享这个过程。问一个问题,当开启了 System.setProperty(RpcConfigs.DISPATCH_MSG_LIST_IN_DEFAULT_EXECUTOR,"false");
是会影响全局吗,就是不能使用这个特性了。
from sofa-bolt.
是的, 如果要修改这一行为, 需要定制 RpcCommandHandler, 然后重新注册一个 Protocol , .现在默认启用的是: com.alipay.remoting.rpc.protocol.RpcProtocol
from sofa-bolt.
是的, 如果要修改这一行为, 需要定制 RpcCommandHandler, 然后重新注册一个 Protocol , .现在默认启用的是: com.alipay.remoting.rpc.protocol.RpcProtocol
🆗
from sofa-bolt.
RpcConfigs.DISPATCH_MSG_LIST_IN_DEFAULT_EXECUTOR
的默认值是true
,所以默认就会放到线程池执行,无法保证顺序。
@chuailiwu 针对这些配置,我们可以在文档里面补充一下?
from sofa-bolt.
RpcConfigs.DISPATCH_MSG_LIST_IN_DEFAULT_EXECUTOR
的默认值是true
,所以默认就会放到线程池执行,无法保证顺序。@chuailiwu 针对这些配置,我们可以在文档里面补充一下?
ok, i create a demo(#325) first
from sofa-bolt.
Related Issues (20)
- Hessian serializer memory optimization
- 如何修改jraft中bolt的日志路径 HOT 1
- DefaultInvokeFuture Why need to switch class loaders? HOT 2
- Bug: Missing version number causes project to fail to compile
- 有概率无法获取连接吗? HOT 1
- 多线程环境下添加EventProcessor报错 HOT 3
- com.alipay.remoting.rpc.exception.InvokeTimeoutException: Rpc invocation timeout[responseCommand TIMEOUT] HOT 4
- 客户端请求超时 HOT 1
- SyncUserProcessor和AsyncUserProcessor保持相同的业务抛异常语义。即服务端异步处理请求时,如果AsyncUserProcessor处理过程中遭遇exception,调用端可以通过catch exception进行处理,而不是通过instance of判断响应的类型。 HOT 3
- AbstractBatchDecoder 中的判断换种写法是不是更好理解? HOT 1
- Bolt can not run without hessian HOT 1
- How does SOFABolt ensure machine performance issues? HOT 1
- RpcClient 的 oneway 方法可以设置发送时的顺序吗 HOT 2
- Bolt是否支持JDK17 LTS版本? HOT 6
- RpcClient发送大size的请求会返回CLIENT_SEND_ERROR HOT 1
- Diffrent thread send heartbeat to server at the same time HOT 5
- debug日志报出Please check your pipeline configuration HOT 7
- Why "Unknown protocol code: [ProtocolVersion{version=[3]}] while decode in ProtocolDecoder.]" warning message reported in connection-event log file? HOT 2
- Add closed check in Connection's isFine HOT 2
- hessian dependency conflict HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sofa-bolt.