zoukankan      html  css  js  c++  java
  • SpringCloud、dubbo 和 druid 问题总结

    背景:

      我们当前的微服务架构采用的是 SpringCloud 全家桶 + dubbo + druid + apllo 等技术集成的。

    1、多服务实例相同端口冲突问题

      目前线上服务器内容动辄 128 ~ 256GB,我们一个服务最大内存设置不超过 32GB,那么为了有效利用服务器资源,我们都会在一台服务器上启动多个服务实例。那此时如果配置文件中配置写死了一个固定的 port 就会发生 dubbo 服务端口冲突。需要将 dubbo 的端口设置为 随机端口,具体如下所示:

    dubbo:
      scan:
        base-packages: com.search.bs
      protocol:
        name: dubbo
        port: -1 #20881,将原来写死的 20881 改为随机,默认端口为 20880
        serialization: hessian2
    

     2、mysql 加载超时问题

      链接 mysql 我们使用的是 druid 的数据库连接池,我们当前业务涉及到正排加载,而有的业务线数据量较大,且得到对应需要的正排内容加载查询的时候会很慢,导致前一个加载完成后紧接着加载第二个内容的时候,此时 mysql 链接不可用,或者当前的链接耗时太长也导致不可用状态:

    druid:
        #初始化大小,最小,最大
        initial-size: 10
        max-active: 300
        min-idle: 5
        #配置获取连接等待超时的时间
        max-wait: 300000
        #检测连接是否有效的sql
        validation-query: "select '1'"
        validation-query-timeout: 2000
        #从连接池里面获取连接时都会测试连接的有效性。这个是获取一个稳定连接最简单有效的手段,前提是如果你的性能要求不是非常高
        test-on-borrow: true
        test-on-return: false
        #对已经取到的connection进行连接有效性的检测
        test-while-idle: true
        #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
        time-between-eviction-runs-millis: 60000
        #配置一个连接在池中最小生存的时间,单位是毫秒
        min-evictable-idle-time-millis: 300000
        remove-abandoned: true
    

     其中最重要的是将:test-on-borrow 设置为 true,因为我们只是在初始化的时候加载正排,所以无所谓性能要求。

    3、服务注册回调异常

    有一同事的 mac 升级为最新版本,导致最近的整个微服务架构启动不起来了,一直卡在某个错误上,先来看一段警告信息:

    [2020-04-14 18:19:49,391][dev][WARN][main][] o.a.d.c.AbstractConfig -  [DUBBO] Connection refused (Connection refused), dubbo version: 2.7.3, current host: 172.18.18.95
    java.net.ConnectException: Connection refused (Connection refused)
    	at java.net.PlainSocketImpl.socketConnect(Native Method)
    	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    	at java.net.Socket.connect(Socket.java:589)
    	at org.apache.dubbo.config.ServiceConfig.findConfigedHosts(ServiceConfig.java:698)
    	at org.apache.dubbo.config.ServiceConfig.doExportUrlsFor1Protocol(ServiceConfig.java:560)
    	at org.apache.dubbo.config.ServiceConfig.doExportUrls(ServiceConfig.java:457)
    	at org.apache.dubbo.config.ServiceConfig.doExport(ServiceConfig.java:415)
    	at org.apache.dubbo.config.ServiceConfig.export(ServiceConfig.java:378)
    	at org.apache.dubbo.config.spring.ServiceBean.export(ServiceBean.java:336)
    	at org.apache.dubbo.config.spring.ServiceBean.onApplicationEvent(ServiceBean.java:114)
    	at org.apache.dubbo.config.spring.ServiceBean.onApplicationEvent(ServiceBean.java:60)
    	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
    	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
    	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
    	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:402)
    	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:359)
    	at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:896)
    	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:162)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:552)
    	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
    	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744)
    	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391)
    	at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
    	at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:140)
    	at com.mfw.search.bs.SearchBsBootstrap.main(SearchBsBootstrap.java:23)
    

     此时该服务在 nacos 注册中心是已经注册成功的,但是对应的服务 ip 为:127.0.0.1,而从日志中报出来的信息当前 ip 为:172.18.18.95,从异常信息中直观的可以看到是 socke 拒绝连接,也就是说:

      在本地启动dubbo时,服务注册在 nacos 上,但是注册IP却不是本地的iP。产生问题,导致consumer 找不到provider ,访问不了服务。

    • 例如 本地IP为 172.18.18.95 ,但是 nacos 上的注册 ip 可能是 127.0.0.1

      从网上查了好多说修改 /etc/hosts,但是并没有解决这个问题,而且明明之前是好使的,周边没有升级的小伙伴使用他当前 git 分支代码启动也是一点问题都没有,这就奇怪了,难道真的是mac 电脑升级导致的吗?

      但是不管是不是升级导致的,这个问题还是需要解决的。首先我们需要明确问题的原因:

        1. 客户端向 nacos 发起请求注册成功

        2. 通过服务端回调的时候通过 127.0.0.1 无法回调回去(因为你的真实 ip 为 172.18.18.95),导致 socket 拒绝连接

      debug dubbo 代码发现,在 NetUtils 中的 getLocalAddress0 这个方法,获取到的 ip 为 localhost/127.0.0.1,而且设置完对应的 hosts 也不受影响,所以我们的想法也很简单,需要改动 dubbo 的相关配置来约束相应的 ip 地址:(只有本地环境可能会发生这种问题,线上不会存在,所以在一定程度上可以这么做)

    dubbo:
      scan:
        base-packages: com.mfw.search.bs
      protocol:
        name: dubbo
        port: -1
        serialization: hessian2
        host: 172.18.18.95 #指定好当前本机 ip 地址
    

     相应的 spring相关配置也需要指定当前注册的服务的 ip 地址为某个段内的,可以将 127.0.0.1 屏蔽掉:

    spring:
      autoconfigure:
        exclude:
          - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
      application:
        name: search-bs-lyx #应用名。很重要!是注册中心的主键,gateway路由也需要靠它
      main:
        allow-bean-definition-overriding: true
      cloud:
        nacos: #采用nacos注册中心
          discovery:
            enabled: true
            register-enabled: true
            namespace: 6947fa15-b976-45f4-b121-4c05e802e8xx
            endpoint: 'nacosendpoint.mtech.svc.ab:8098'
        inetutils:
          preferred-networks: 172 #限定选择前缀为 172 的 ip
    

     这样就能解决以上问题,一般情况下 dubbo 是不需要指定 ip 的,但是如果不指定解决不了再指定一定会解决掉问题,这个主要就是绑定 nacos 注册的时候使用的 ip 地址

    而 spring 规范的前缀 ip,这个主要是指定 nacos 注册的服务分配的 ip,具体如下图的一个服务启动在 nacos 中的服务注册情况,可以对照 dubbo 和 spring 配置的 ip 来区分对待:

  • 相关阅读:
    Spring Security【一】 ------ 前后端分离开发
    mybatis 使用mybatis-plus-generator进行代码自动生成
    VuejsApp简介
    BeetleX之Vue ElementUI生成工具
    BeetleX数据分析中间服务V3
    vuejs集成echarts的一些问题
    BeetleX使用bootstrap5开发SPA应用
    BeetleX大数据之产品分析服务
    小试牛刀ElasticSearch大数据聚合统计
    在windows 10的ubuntu系统上如何使用dd命令写u盘?
  • 原文地址:https://www.cnblogs.com/liang1101/p/12702631.html
Copyright © 2011-2022 走看看