Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] proxy local mode send message failed #8904

Open
3 tasks done
VictoryAnn opened this issue Nov 8, 2024 · 25 comments
Open
3 tasks done

[Bug] proxy local mode send message failed #8904

VictoryAnn opened this issue Nov 8, 2024 · 25 comments

Comments

@VictoryAnn
Copy link

Before Creating the Bug Report

  • I found a bug, not just asking a question, which should be created in GitHub Discussions.

  • I have searched the GitHub Issues and GitHub Discussions of this repository and believe that this is not a duplicate.

  • I have confirmed that this bug belongs to the current repository, not other repositories of RocketMQ.

Runtime platform environment

windows11

RocketMQ version

5.3.1

JDK Version

1.8

Describe the Bug

本地部署了两个local proxy,proxy1,proxy2,当作两个分片,其中proxy1创建topic: 1a,另外一个proxy2创建topic: 2b,客户端地址配置两个proxy的地址,写其中一个topic,比如 1a ,可能会失败,当请求到的proxy2的时候,客户端会报错,获取topicroute失败,导致无法发送消息。

Steps to Reproduce

image
image

What Did You Expect to See?

正常应该能获取到topicRoute,因为proxy获取路由是从nameserver获取的。

What Did You See Instead?

客户端获取路由失败,终止发送消息。

Additional Context

No response

@dyrnq
Copy link

dyrnq commented Nov 9, 2024

由于 Local 模式下 Proxy 和 Broker 是同进程部署,Proxy本身无状态,因此主要的集群配置仍然以 Broker 为基础进行即可。参考

那么两个broker是什么关系啊?

@VictoryAnn
Copy link
Author

由于 Local 模式下 Proxy 和 Broker 是同进程部署,Proxy本身无状态,因此主要的集群配置仍然以 Broker 为基础进行即可。参考

那么两个broker是什么关系啊?

考虑local模式下,broker 可能会扩容,broker 扩容后有多个分片,然后创建topic可以指定broker ,就会出现现在这种情况,这个场景是预期内的吗?

@dyrnq
Copy link

dyrnq commented Nov 9, 2024

Proxy本身无状态的,确实如此啊

@VictoryAnn
Copy link
Author

所以,local 模式下,只能本地proxy 访问本地的broker 吗?我看源码proxy 是从nameserver 获取topic路由,理论上是可以转发到其他切片上?

@dyrnq
Copy link

dyrnq commented Nov 9, 2024

不确定local模式下会不会连上namesrv,试下从broker剥离分开部署proxy,因为单独部署proxy会配置namesrvAddr这个参数

@dyrnq
Copy link

dyrnq commented Nov 9, 2024

@VictoryAnn
Copy link
Author

看以上2图,能看出点端倪来

这个图有点疑问,就是client需要先获取所有topic路由,用了proxy和broker 同一个进程的话,获取到的路由地址会被proxy替换成proxy的端口,然后根据对应topic所在的proxy,客户端会选择对应的proxy地址去send message。但是现状看起来是客户端获取topic路由的时候,由于topic不在当前broker上,导致路由信息返回的message type 为 0,客户端获取不到topic路由。
image

@dyrnq
Copy link

dyrnq commented Nov 11, 2024

确实如此了,那得要求client自行判断了

@VictoryAnn
Copy link
Author

那现在的问题就是,客户端从proxy获取路由报错,Message type is not specified,是不是proxy提供的获取路由接口存在问题?期望是,proxy会返回全量的topicRoute,并且返回内容可以被客户端正确解析。

@dyrnq
Copy link

dyrnq commented Nov 11, 2024

那现在的问题就是,客户端从proxy获取路由报错,Message type is not specified,是不是proxy提供的获取路由接口存在问题?期望是,proxy会返回全量的topicRoute,并且返回内容可以被客户端正确解析。

这样比较好

@dyrnq
Copy link

dyrnq commented Nov 11, 2024

Caused by: java.lang.IllegalArgumentException: Message type is not specified
also see #8546

@dyrnq
Copy link

dyrnq commented Nov 12, 2024

对比以上代码,发现LocalMetadataService确实没有通过Namesrv请求路由信息,你是从哪里看到过Local模式有能获取路由信息的表述吗? @VictoryAnn

@VictoryAnn
Copy link
Author

VictoryAnn commented Nov 12, 2024

对比以上代码,发现LocalMetadataService确实没有通过Namesrv请求路由信息,你是从哪里看到过Local模式有能获取路由信息的表述吗? @VictoryAnn
是获取topic路由的接口。getTopicRouteForProxy

@dyrnq
Copy link

dyrnq commented Nov 12, 2024

嗯,对比了下这俩类的getTopicRouteForProxy方法
唯一的区别就是grpcPort和requestHostAndPortList

return new ProxyTopicRouteData(topicRouteData, grpcPort); // grpcPort是不带IP的啊,他过不去另外的机器啊
return new ProxyTopicRouteData(topicRouteData, requestHostAndPortList);

@VictoryAnn
Copy link
Author

我看是从这里cache获取的,cache是从nameserver获取的,proxy只是替换了端口(这里也存疑,cluster部署可能端口都是一致的,不会有问题。如果像local部署,不同的代理端口不同是不是也有问题?),不需要去访问其他机器。
image

@dyrnq
Copy link

dyrnq commented Nov 12, 2024

grpcPort等同于仅仅包含了一个元素的List<Address>,所以相当于又过滤了?

@dyrnq
Copy link

dyrnq commented Nov 12, 2024

还是把proxy从 broker拆分部署吧,这个是没有问题的。入口不从namesrv,元信息就获取不到,local模式怪怪的。

@VictoryAnn
Copy link
Author

还是把proxy从 broker拆分部署吧,这个是没有问题的。入口不从namesrv,元信息就获取不到,local模式怪怪的。

local这块是感觉怪怪的,还有一个疑问点,local部署下,如果client不去获取topicRoute,直接sendmessage proxy是不是会自己转到其他的proxy,那这样client似乎没必要获取topicRoute?尽管是cluster,客户端连代理的话,有必要获取topicRoute吗?这是为了兼容nameserver的访问方式吗,还是有其他考量?

@dyrnq
Copy link

dyrnq commented Nov 12, 2024

第一个回答不了(非官方人员:( )
第二个(作为用户)感觉有必要,毕竟proxy和namesrv类似的入口能力,像你这样划分topic的话,确实proxy需要知道topic具体落地到那个broker上,有点类似nginx的动态配置,比如/hello --->upstream 到后端,那么后端必须得能承接 /hello的访问,所以不管是namesrv或者proxy 都得做到这个匹配能力,不然用户得自己配置(提供配置入口,感觉也没必要)?

@VictoryAnn
Copy link
Author

个人感觉,topic路由相关的应该在proxy内部做掉,proxy的角色也是对外屏蔽掉broker和nameserver,proxy外层加负载均衡即可。

@dyrnq
Copy link

dyrnq commented Nov 12, 2024

嗯,唯一的区分就是local Proxy怎么定义了,按道理这里的local proxy的这个叫法有点让人误解,如果要是叫 broker 提供grpc协议入口会更合适。

即这个broker提供grpc协议又提供remoting协议。

这个和grpc的这个提供能力的叫法有关系,分离部署就叫proxy,合并启动就叫只负责自个的grpc。

@dyrnq
Copy link

dyrnq commented Nov 12, 2024

所以我怀疑local proxy 是用 grpc over remoting 替代了一个假设的存在(即原生的grpc能力)

@VictoryAnn
Copy link
Author

嗯,唯一的区分就是local Proxy怎么定义了,按道理这里的local proxy的这个叫法有点让人误解,如果要是叫 broker 提供grpc协议入口会更合适。

即这个broker提供grpc协议又提供remoting协议。

这个和grpc的这个提供能力的叫法有关系,分离部署就叫proxy,合并启动就叫只负责自个的grpc。

赞同,所以提供local这种部署模式 目的有点模糊,官方的资料给的都是跟cluster部署没什么区别,主要可以降低延迟,但实际分析下来,又给人感觉local仅仅是broker的替身。

@dyrnq
Copy link

dyrnq commented Nov 12, 2024

嗯,唯一的区分就是local Proxy怎么定义了,按道理这里的local proxy的这个叫法有点让人误解,如果要是叫 broker 提供grpc协议入口会更合适。
即这个broker提供grpc协议又提供remoting协议。
这个和grpc的这个提供能力的叫法有关系,分离部署就叫proxy,合并启动就叫只负责自个的grpc。

赞同,所以提供local这种部署模式 目的有点模糊,官方的资料给的都是跟cluster部署没什么区别,主要可以降低延迟,但实际分析下来,又给人感觉local仅仅是broker的替身。

如果local proxy 等同于只给broker提供grpc的能力,那么入口就还得是namesrv,以效仿于remoting的形式获取topic和grpc broker的关联路由关系。

不过好像rocketmq-v5的客户端还不支持endpoints写namesrv

ClientConfiguration clientConfiguration = ClientConfiguration.newBuilder()
            .setEndpoints(endpoints)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants