weibocom / motan

A cross-language remote procedure call(RPC) framework for rapid development of high performance distributed services.
Other
5.89k stars 1.78k forks source link

jersey里面使用consul作为注册中心出错,zookeeper就不会 #398

Open charlieyu opened 7 years ago

charlieyu commented 7 years ago

server使用SE的项目,注册中心使用consul。在jersey中集成client端。调用的时候出错。报 Error creating bean with name 'generatorId': FactoryBean threw exception on object creation; nested exception is com.weibo.api.motan.exception.MotanFrameworkException: error_message: ClusterSupport No service urls for the refer:motan://192.168.1.207:0/default_rpc/com.hangyu.uniqueId.IGeneratorId/1.0/referer, registries:[consul://192.168.1.207:8500/com.weibo.api.motan.registry.RegistryService?group=default_rpc], status: 404, error_code: 10101,r=null 这里有个问题,就是server的正确地址是 192.168.1.207:8082 不是 192.168.1.207:0。 如果客户端不是集成到jersey,而是写成独立的SE项目是可以调用到的。

如果改成zookeeper做注册中心就没有这个问题。

rayzhang0603 commented 7 years ago

这个异常是指client没有从注册中心找到working状态的节点。192.168.1.207:0是指client端自身,不是指server。 可以确认server端的提供服务开关是否打开了。需要在server端打开下面开关,server才会正常提供服务。

MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, true);

可以在管理后台查看一下server的状态是不是working。

longshang commented 7 years ago

server的状态已经working了,请问还有哪些原因导致的

rayzhang0603 commented 7 years ago

server和client的group、protocol是否一致?可以查询一下consul的/v1/health/service/${your_group_name} ,看看有没有对应server信息?

longshang commented 7 years ago

@rayzhang0603 ,感谢您的回复,我刚刚查了,可以看到对应的server信息: "Checks": [ { "Node": "conan", "CheckID": "serfHealth", "Name": "Serf Health Status", "Status": "passing", "Notes": "", "Output": "Agent alive and reachable", "ServiceID": "", "ServiceName": "", "CreateIndex": 4, "ModifyIndex": 4 }, { "Node": "conan", "CheckID": "service:192.168.1.125:8003-com.hang.uniqueId.IGeneratorId", "Name": "Service 'motanrpc_default_rpc' check", "Status": "passing", "Notes": "", "Output": "", "ServiceID": "192.168.1.125:8003-com.hang.uniqueId.IGeneratorId", "ServiceName": "motanrpc_default_rpc", "CreateIndex": 133069, "ModifyIndex": 133089 } ] }

但在您的源码里:ConsulEcwidClient.java中的 Response orgResponse = client.getHealthServices( serviceName, true, queryParams); 报json解析问题:Caused by: com.google.gson.JsonParseException: The JsonDeserializer EnumTypeAdapter failed to deserialized json object "passing" given the type class com.ecwid.consul.v1.health.model.Check$CheckStatus

rayzhang0603 commented 7 years ago

com.ecwid.consul.v1.health.model.Check$CheckStatus类是有passing这个枚举值的,可以debug看一下com.ecwid.consul client的解析,看是不是gson版本或者com.ecwid.consul版本不兼容问题。

longshang commented 7 years ago

@rayzhang0603 ,我们是用0.3.1版本,发现这个com.ecwid.consul库的GsonFactory代码中没有初始化枚举解析器,不知是BUG还是?我现在加入解析器就好了,麻烦您帮忙看看,这样子加是否有问题,如下代码: /**

longshang commented 7 years ago

@rayzhang0603 ,麻烦您看看,我们是用0.3.1版本,发现这个com.ecwid.consul库的GsonFactory代码中没有初始化枚举解析器,不知是BUG还是?我现在加入解析器就好了,麻烦您帮忙看看,这样子加是否有问题,如下代码: /**

@author Vasily Vasilkov (vgv@ecwid.com) */ public class GsonFactory { private static final GsonBuilder GSON_BUILDER = new GsonBuilder(); private static final ThreadLocal GSON = new ThreadLocal() { @Override protected Gson initialValue() { GSON_BUILDER.registerTypeAdapter(Check.CheckStatus.class, new GsonEnumTypeAdapter(Check.CheckStatus.PASSING)); //我fix的代码段 return GSON_BUILDER.create(); } }; public static Gson getGson() { return GSON.get(); } }

rayzhang0603 commented 7 years ago

@freejohn consul-api中已经加入了gson的@SerializedName()注解,应该是什么原因导致注解并未生效,建议排查一下注解未生效的原因,单纯注册passing状态,遇到其他类型或其他字段字段仍然可能出问题。