apache / dubbo-admin

The ops and reference implementation for Apache Dubbo
https://dubbo.apache.org
Apache License 2.0
4k stars 2.17k forks source link

获取元数据有问题 #474

Closed bungder closed 5 years ago

bungder commented 5 years ago

在页面上的“服务查询”里点击“查询结果”里的“详情”进去,会报错。 image

2019-08-02 14:40:04.531 ERROR 16813 --- [tp-nio-8979-exec-1] o.a.d.a.handler.CustomExceptionHandler     46:  [DUBBO] [SystemException]Exception:, dubbo version: 2.7.2, current host: 172.17.0.1

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:226)
    at com.google.gson.Gson.fromJson(Gson.java:927)
    at com.google.gson.Gson.fromJson(Gson.java:892)
    at com.google.gson.Gson.fromJson(Gson.java:841)
    at com.google.gson.Gson.fromJson(Gson.java:813)
    at org.apache.dubbo.admin.controller.ServiceController.serviceDetail(ServiceController.java:99)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
    at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:215)
    ... 59 common frames omitted

(实际上上面这一个异常日志默认是没有打出来的,需要设置dubbo的LoggerAdapter:LoggerFactory.setLoggerAdapter(new org.apache.dubbo.common.logger.slf4j.Slf4jLoggerAdapter());)

获取元数据是在dubbo-admin-server/src/main/java中的org.apache.dubbo.admin.controller.ServiceController里的serviceDetail方法中完成的,当使用zk作为注册中心的时候,String metadata = providerService.getProviderMetaData(identifier);这里,metadata127.0.0.1,debug进去的话,在org.apache.dubbo.admin.registry.metadata.impl.ZookeeperMetaDataCollector中,doGetMetadata方法里的pathdubbo/metadata/com.bungder.test.SampleService/provider/sample-service-impl,但是实际上,zk里在这个路径下,只有一个名为service.data的property,如果path加上/service.data,那么就能获取到正确的json字符串,否则只会获取到127.0.0.1,然后页面上还是看不到元数据。

image

如果我在org.apache.dubbo.admin.registry.metadata.impl.ZookeeperMetaDataCollector的doGetMetadata方法里加上判断:

if (!path.endsWith("service.data")) {
    path += "/service.data";
}

在页面上的“服务查询”里点击“查询结果”里的“详情”进去能正常看到元数据,但是在“服务测试”里搜索却又出错了,因为这里也会调用到org.apache.dubbo.admin.registry.metadata.impl.ZookeeperMetaDataCollectordoGetMetadata方法。

使用的dubbo-admin版本是develop分支里最新的提交:

commit 3aea527d387999a2949eee3324cc9a8b3178d123
Author: 孙不服 <sunyoubufu@163.com>
Date:   Mon Jul 8 09:31:53 2019 +0800

    add 'weight' label to provider list #130 (#435)

另外运行的服务提供者使用的dubbo版本是2.7.1

bungder commented 5 years ago

解决了。

这实际上是版本差异导致的。dubbo-admin使用的dubbo版本是2.7.2,而我服务提供者使用的版本是2.7.1,因为需要用到dubbo-spring-boot-starter,而dubbo-spring-boot-starter官方版本最新的只是2.7.1。我自己手动将dubbo-spring-boot-starter里的版本升级到2.7.2之后,服务提供者也将依赖版本升级到2.7.2就可以了。升级之后可以看到zk里metadata的存储路径变了。

另外有一点需要提一下,从2.7.1升级到2.7.2,需要将zk里的注册信息清理掉,不然会启动不起来。