线上使用spring cloud

刚从零开始上线了一套基于SpringCloud的微服务应用,遇到了一些坑,在三月份的最后一天做一个总结

技术选型

首先讲下技术选型,在微服务领域两大巨头,Dubbo和SpringCloud,近期关注微服务的朋友们可能知道,例如Erueka,Hystrix,Zuul这些貌似都已经停止更新了,虽然他们官网上说,现有的版本已经满足现有的需求,但软件领域,睡一觉就是另一个样,但好在,Spring积极在解决这些问题,基本上也都有替代品,比如全套的阿里系微服务spring-cloud-alibaba。

为什么放弃dubbo这个微服务框架呢,首先第一点,dubbo基于RPC通信,类似thrift,用过thrift的朋友,都知道,虽然thrift这个框架非常厉害,它可以调用其他语言的服务,java调python啊,python调c啊这些,而且性能非常不错。但有一点,一旦你的接口有变动,那所有涉及到这个接口的实现服务,都需要重新生成一遍对应语言的接口并依赖新生成的接口完成实现,实在是非常麻烦

Dubbo没有thrift那么麻烦,但如果新加入了接口类,就一定要在提供方和调用方同时配置一堆东西,如果分组开发,由此产生的沟通成本将非常昂贵,我们项目要求快速迭代,因此,放弃Dubbo的RPC协议,使用基于Http的Sping Cloud体系,而且由业务推倒,后期服务可能不会过于复杂,因此,服务降级显得不那么重要,如果后期涉及相关问题,可以采用阿里套餐中[Sentinel]组建,以资源的方式来帮助我们处理服务降级相关的问题。

构建

为了践行OpsDev快速迭代,必然是要采用自动化部署的,选用的是老牌自动化部署工具[Jenkins],但也由此产生了一个小问题,Jenkins是从git上获取代码,本地编译后通过脚本部署的,但git无法拉取某个路径下的代码,所以只能吧项目分开,使用多个git仓库管理,原本项目是使用svn进行托管,微服务项目可以放在一个工程下,同时打开整个微服务工程,但现在看来没办法这么做了。

分享一下部署脚本

#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/jdk1.8.0_191/bin:/usr/local/elasticsearch-6.5.4/bin:/root/bin
PATH=.:$PATH
export PATH

JENKINS_NAME=$1
ARTIFACT_ID=$2
SPRING_PROFILE=$3

echo $JENKINS_NAME $ARTIFACT_ID $SPRING_PROFILE

if [ ! -d "/data/webapp/$JENKINS_NAME" ]; then
  mkdir /data/webapp/$JENKINS_NAME
fi

SING_STR="\$\\"
cd /data/webapp/deployScript
mv $JENKINS_NAME-0.0.1-SNAPSHOT.jar $JENKINS_NAME-0.0.1-SNAPSHOT_bak.jar

scp -P22  xxxx@xxx.xxx.xxx.xxx:"/data/webapp/.jenkins/jobs/$JENKINS_NAME/modules/com.thinkerjet$SING_STR$ARTIFACT_ID/lastSuccessful/archive/com.thinkerjet/$ARTIFACT_ID/0.0.1-SNAPSHOT/$ARTIFACT_ID-0.0.1-SNAPSHOT.jar" ./$JENKINS_NAME-0.0.1-SNAPSHOT.jar

spring_pid=`ps -ef | grep $JENKINS_NAME | grep -v grep | grep -v deploy_lexin_boot.sh| awk '{print $2}'`
[ -n "$spring_pid" ] && kill -9 $spring_pid

cp $JENKINS_NAME-0.0.1-SNAPSHOT.jar /data/webapp/$JENKINS_NAME/$JENKINS_NAME-0.0.1-SNAPSHOT.jar
cd /data/webapp/$JENKINS_NAME
/usr/bin/nohup java -jar $JENKINS_NAME-0.0.1-SNAPSHOT.jar --spring.profiles.active=${SPRING_PROFILE} > /data/webapp/$JENKINS_NAME/catalina.out 2>&1 &

jenkins来执行远程脚本,通过scp命令获取打包好的文件,然后执行一下就OK了,另外,不要用lsof -i 这个天杀的命令
它会把所有跟那个端口有通讯的进程都查出来,比如,你如果用lsof -i:eureka端口,那么你部署在这台机器上的其他微服务,全被kill了

开发

基于Greenwich.SR1版本开发
未完待续

遇到的坑

  1. 使用OpenFeign时,使用@FeignClient注解,会在Bean容器中生成Bean对象,如多个@FeignClient注释的类使用相同服务,无法启动

    • 解决方法:@FeignClient(name = "服务名称", contextId = "类名")
  2. 使用OpenFeign时,服务间调用默认1秒失败,会出现服务调用成功,但响应超时 - ReadTimeOut,使数据不一致

    • 解决方法:设置ribbon超时时间 (OpenFeign底层调用ribbon以及Hystrix),高版本中默认Hystrix不开启
        ribbon:
          ReadTimeout: 60000
          ConnectTimeout: 60000
    
  3. 微服务部署时,需要先让路由getway停止路由到被部署服务,以防请求过程中服务重启

    • 解决方法:使用spring-boot-starter-actuator优雅关闭服务
    • 添加spring-boot-starter-actuator,默认shutdown等端点为关闭状态,启动shutdown端点,访问http:localhost:xxxx/actuator/shutdown
        management:
          endpoint:
            shutdown:
              enabled: true
          endpoints:
            web:
              exposure:
                include: shutdown
              base-path: /
    
  4. 配置拦截器无法Autowired

    • 解决方法:使用WebApplicationContextUtils.getRequiredWebApplicationContext方法获取bean工厂,后加载
        private Foo foo;
        ...
        if (foo == null) {
            BeanFactory factory = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
            foo = factory.getBean(Foo.class);
        }
    
  5. 日志输出

    • 方法:使用SpringBoot内置文件输出,注:该配置只应在生产环境中使用
        logging:
            path: 此处建议设置为服务器中jar路径下,新建工程同名文件夹,用来保存该项目日志
    
  6. 接口保护

    • 方法:在getway中配置2级路径,如不希望外界路由该接口,则在第一级路径区分,内部服务使用/provider,提供给外部的服务使用/api
        spring:
          application:
            name: gateway-service
          profiles:
            active: dev
          cloud:
            gateway:
              routes:
                - id:  xxxx
                  uri: lb://business
                  predicates:
                    - Path=/business/**
                  filters:
                    - StripPrefix=1     //该配置表示如访问该服务,则不传递/business/路径
                                    //例如前台访问/businsess/foo, 则服务真实控制器路径为/foo
                - id:  interface
                  uri: lb://interface
                  predicates:
                    - Path=/api/**      //表示只有/api/为一级路径的控制器才可以被路由访问
    
  7. 生产环境Eureka高可用,及unavailable-replicas问题

    • eureka.instance.appname必须与spring.application.name相同
    • eureka.instance.hostname必须使用hosts名称映射,修改hosts文件
    • eureka.client.fetch-registryeureka.client.register-with-eureka要么不写,要么必须为true
        server:
          port: 8761
        eureka:
          instance:
            leaseRenewalIntervalInSeconds: 5
            leaseExpirationDurationInSeconds: 10
          server:
            enable-self-preservation: true
            evictionIntervalTimerInMs: 5000
            useReadOnlyResponseCache: false
          client:
            fetch-registry: true
            register-with-eureka: true
        spring:
          application:
            name: xxx
          profiles:
            active: prod-1
        logging:
          level:
            com.netflix: INFO
        ---
        server:
          port: 8761
        spring:
          profiles: prod-1
        eureka:
          instance:
            hostname: service-eureka-01
            appname: xxx
          client:
            serviceUrl:
              defaultZone: http://service-eureka-02:8762/eureka
        ---
        server:
          port: 8762
        spring:
          profiles: prod-2
        eureka:
          instance:
            hostname: service-eureka-02
            appname: xxx
          client:
            serviceUrl:
              defaultZone: http://service-eureka-01:8761/eureka
    

总结

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350

推荐阅读更多精彩内容