zoukankan      html  css  js  c++  java
  • 搭建Spring Cloud+Dubbo

      公司要测试一下zipkin是否可以跟踪全流程,项目的架构比较复杂,不要问我为什么,基本架构如下:前端门户,调用spring cloud组件,spring cloud在调用dubbo,这样一套流程。于是在spring cloud以及dubbo搭建过程中的所坑所思所想,记录一下。

      ZUUI配置服务出错

    不知为何在ZUUI里面配置serviceId无法从Eureka里面获取服务名称;但是如果配置为url,则可以跳转。

    问题:为什么服务没有配通,怎么配服务,serviceId是对应Eureka里面的Application Name吗?

    拿“http://localhost:8083/springcloudapp/hello/JIm”来举例,其实springcloudapp部分其实服务部分,即你想要请求的服务(或者说服务所在机器的IP:Port,这些信息在Eureka里面存放,交给ZuuL就行了),/hello/Jim才是真正的要IP地址之后的请求信息。但是发现如果是服务部分是服务名称(Eureka里面的Application)没有问题,但是但是假如是下面的定义方式,路径转服务,则失败;

    1     zuul: 
    3       routes: 
    5           hello: 
    7         path: /hello/*
    9         serviceId: springcloudapp

    后来调研发现原来path路径一个“*”只能匹配一个"/"内容,想要匹配多个“/"内容,需要添加"**",才可以匹配上http://localhost:8083/springcloudapp/hello/JIm;这种匹配方式是参考了Ant的匹配规则

        zuul:
          routes: 
              hello: 
            path: /hello/**
            serviceId: springcloudapp

    问题解决。

    问题:为什么ZUUI没有在Eureka里面注册?

    添加一下依赖即可。

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>

    其实经过配置,只要在日志中看到如下的内容,及说明配置注册到Eureka是生效的:

    demoService为空

    原来需要把consumer.xml文件放到WEB-INF下面,然后在web.xml中进行配置(在servlet节点下配置param-value);这里其实有一个问题,就是application和WEB工程之间的差别,就是Spring配置文件的放置;application有默认放置就是class-path下面;但是对于web工程,则需要进行显式的声明(或者默认是servlet-name同名的.xml文件)。也就是说配置文件编译的路径有差异;

    1     <servlet>
    2         <servlet-name>spring-webmvc</servlet-name>
    3         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    4         <load-on-startup>1</load-on-startup>
    5         <init-param>
    6             <param-name>contextConfigLocation</param-name>
    7             <param-value>/WEB-INF/consumer.xml,/WEB-INF/spring-webmvc-servlet.xml</param-value>
    8         </init-param>
    9     </servlet>

    除此之外工程引用上也有区别,体现在application的工程只需要在pom文件中引用对应的内容;但是对于web工程处理在pom文件中需要处理(用于保证代码编译不出错),还需要在asembly deployment中添加工程引用,才能保证运行是能够正常找到类文件。

      其实到了最后你会发现,consumer.xml和spring-webmvc-servlet.xml其实可以合并为一个,关键是要理解xml里面的标签,比如xml文件中声明dubbo标签(例如,dubbo:annotation),你就需要在beans中声明dubbo的命名空间xmlns:dubbo="http://code.alibabatech.com/schema/dubbo";当然这个网址是否存在并不重要;但是xml解析器将会校验所有的出现的标签需要在beans中声明其命名空间。之所以很多时候spring-mvc.xml和applicationContext会分开更多的是出于清晰的原因,否则其实所有的spring的配置文件都可以捏在一起。

    添加了zipkin之后,dubbo的web-consumer报错:

    Invalid bean definition with name 'tracing' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Could not resolve placeholder 'zipkin.dubbo-consumer-web' in string value "${zipkin.dubbo-consumer-web}"; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'zipkin.dubbo-consumer-web' in string value "${zipkin.dubbo-consumer-web}"

    直接写名字不再用${}的形式。

    java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet

    惊讶于竟然是因为在Deployment Assembly中,把maven Dependency路径给删掉!重新添加上,问题解决。这个是在google上的stackoverflow中找到的答案。整整调了我大概一个小时。好像是说对pom文件做了比较大的改动之后,Deployment assembly这个引用就会丢失。

    log4j的2.0版本下载失败;

    但是我的pom文件里面并没有引用log4j,parent的pom文件里面使用的是log4j的1.2.7版本;后来发现:我在properties里面定义了<log4j.version>2.10.0</log4j.version>这样的内容;其实只是靠过来的有腐臭的配置而已;但是也不行,他会自己去找并认为是maven中的一项,因为下载失败而报错。

    发现dubbo的web工程并没有整合zipkin的日志。

    我推测可能是因为web.xml里面没有配置filter导致,添加了filter,后又报错,说是需要添加contextListener,它两是同步添加的吗?研究了一下代码是因为DelegateFilter(brave里面的默认Filter)将会调用spring的WebApplicationContextUtils.getRequiredWebApplicationContext去获取Context,在Context里面将会要求配置context listener,没配置将会报错。

    添加上了listener和filter之后可以正常输出日志。

    Eureka启动的时候报错tomcat异常Address already in use: bind/Tomcat connector in failed state

    这种内嵌tomcat的机制不是spring cloud,其实是spring boot的机制;除了内嵌tomcat,还内置了jetty;后来通过netstat -ano | findstr 8761(8761是Eureka的监听端口)发现确实还在被监听;通过任务管理器通过PID找到了对应的进程删除,问题解决。

    在spring cloud的AppServer里面调用restTemplate报错:java.lang.IllegalStateException: No instances available for 127.0.0.1

    这个异常是因为我在代码总restTemplate是通过autowired方式获取实例的,这种方式restTemplate已经绑定到了Ribbon上面去了;可以通过直接实例化restTemplate的方式来获取restTempate,不再使用@autowired。

    但是,现在的问题是,什么是ribbon?

    Spring cloud提供的负载均衡组件;当两个注册服务同属于一个服务的时候,在客户端通过ribbon进行控制,第一次访问A设备,第二次访问B设备。

    springCloud在添加zipkin发生了问题,就是配置问题;appServer不是web工程,很多之前基于web工程的配置都用上。

    我突然想到其实spring cloud原生应该就该支持zipkin的;在网上一搜果然如此。我下载了一份源码,其实只要添加如下依赖即可。

     1     <dependency>
     2         <groupId>org.springframework.cloud</groupId>
     3         <artifactId>spring-cloud-starter-sleuth</artifactId>
     4     </dependency>
     5     <dependency>
     6         <groupId>org.springframework.cloud</groupId>
     7         <artifactId>spring-cloud-starter-zipkin</artifactId>
     8     </dependency>
     9     <dependency>
    10         <groupId>org.springframework.boot</groupId>
    11         <artifactId>spring-boot-starter-data-rest</artifactId>
    12     </dependency>
    13     <dependency>
    14         <groupId>org.springframework.boot</groupId>
    15         <artifactId>spring-boot-starter-web</artifactId>
    16     </dependency>
    17     <dependency>
    18         <groupId>org.springframework.boot</groupId>
    19         <artifactId>spring-boot-starter-test</artifactId>
    20         <scope>test</scope>
    21     </dependency>

    然后还要在配置文件(yaml或者properties文件)中添加:spring.zipkin.base-url=http://localhost:9411/;

    在调查的过程中还发现zipkin也可以作为一个单独的工程出现,然后所有的对于zipkin的配置都可以在这个工程中进行配置。

    ClassNotFound: org.springframework.boot.autoconfigure.condition.ConditionMessage

    发现是因为少包,spring-boot-autoconfigure,于是添加了这个包的依赖,但是没有写版本;结果发现了下面的异常;

    NoSuchMethodException: org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer

    因为autoconfig默认是1.2.8版本的;所以我觉得可能是因为版本问题,于是直接升到最新的是2.0x,但是不行,改为爆了上面的异常,XX方法找不到,之后就是N次降版本尝试。无解啊,于是我又拿下了svn的上面的demo,照样搞了一下,编译是成功了,但是zipkin没有反应。

    后来我觉得很可能是springcloud配置问题,我又从网上下载了一套spring cloud的demo源码,发现可用。值得深思。

    问题:为什么公司项目的@autowired不好用,无法实例化restTemplate?

    未解决

    Caused by: java.lang.IllegalStateException: Unable to find a single main class from the following candidates
    工程里面有两个main函数,注释掉一个,问题解决
     
    Cannot determine embedded database driver class for database type NONE
    添加@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})

    参考

    https://www.cnblogs.com/brant/p/6298342.html

    https://blog.csdn.net/qq_26562641/article/details/53336899#reply

    https://blog.csdn.net/caicongyang/article/details/52974406

    http://www.baeldung.com/zuul-load-balancing

    https://blog.csdn.net/noaman_wgs/article/details/70214612

    https://github.com/ameizi/dubbo-example

    spring cloud zip的demo

    https://howtodoinjava.com/spring/spring-cloud/spring-cloud-zipkin-sleuth-tutorial/

    ZUUL的配置到Eureka服务发现

    https://blog.csdn.net/zhanglh046/article/details/78651914

     
  • 相关阅读:
    怎样才有资格被称为开源软件
    [翻译]开发Silverlight 2.0的自定义控件
    网上Silverlight项目收集
    Google 分析的基准化测试
    IIS 承载的WCF服务失败
    Lang.NET 2008 相关Session
    Silverlight 2.0 beta1 堆栈
    asp.net 性能调较
    SQL Server 2005 的nvarchar(max),varchar(max)来救火
    LINQPad
  • 原文地址:https://www.cnblogs.com/xiashiwendao/p/8722894.html
Copyright © 2011-2022 走看看