【spring-cloud】spring-cloud-从入门到高可用-下

前面两篇已经介绍了spring-cloud的常用组件作用以及如何在实现项目中搭建,算是比较完整的spring-cloud入门,入门以后接下来就是想着高可用之类的东西了,饱暖思春Y...

这篇主要就讲讲如何搭建高可用又安全的的sping-cloud,以及在spring-cloud中踩到的坑总结.

一:搭建高可用的spring-cloud

在生产环境中,当spring-cloud比较核心的组件比如服务发现中心eureka挂掉了,其他服务均正常,此时却无法对外提供服务,带来大量损失,是不是很蛋疼,所以当服务器充足,且对提供的服务要求较高的稳定性时,可以考虑通过集群的方式,实现高可用,当一台eureka挂了,立马有另外一台补上继续提供服务,有点类似备胎的作用,下面我们就一起来搭建一个具有2个节点的服务注册中心:

其实没啥特别的,只需要在服务发现中心的yml配置中把defaultZone指向另外一台服务器的defaultZone,让它们互相指向,然后把它们部署在不同的服务器上,其它配置与之前不做集群一样,如此就完成了服务注册中心的高可用.

eurka1的application.yml:

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8762/eureka

eureka2的application.yml:

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka

完成之后可以打开看一下: 

访问http://localhost:8761,可以在页面中的DS Replicas中找到eureka2中的ip和端口,这里截图为我正式环境中的截图,不要被误导.

同样的访问http://localhost:8762时也可以在DS Replicas中找到eureka1中的ip和端口号,如此注册中心的高可用便配置好了.

当两个注册中心仍不能完成你对安全可靠性的要求时,你可以搭建3个,4个...方法是一样的

然后来看看各个服务的配置需要做些什么调整:

原来只需要指明一个注册中心的url即可,现在有2个,你只需要用逗号隔开它们即可,以后有3个,4个也同样适用...

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka,http://localhost:8762/eureka

另外相同的服务需要强制把相同服务的application.name命名一致,比如我需要2个配置中心,那么我这两个配置中心的application.name必须都保持一样,比如都为config

否则服务发现中心不会知道它们是两个一样的服务,也就无法实现高可用和负载均衡,服务发现中心会根据你提供的服务名去列表里找一个服务来提供相应服务,具体挑选对应服务列表中的哪个服务是服务发现中心决定的,默认采用轮询的方式,当然你也可以通过修改配置文件实现随机等其他方式.

一般来说比较重要的组件需要配高可用,比如服务发现中心eureka,配置中心config,网关zuul,其他的组件和服务可以根据访问的压力看是否需要配置集群.

 

二:注册中心加密及服务发现加密

当你就这么把所有服务暴露在注册中心,假如有一天别人发现了你服务器的Ip,然后访问了你服务发现中心,发现你的服务发现中心和微服务就这么赤裸裸的暴露着,势必会引起一些接口调用不安全的问题,而且别人的服务也可以注册到你的注册中心,这不是让你免费提供了一台服务器给别人用吗? 基于这些考虑,我们有必要对服务注册中心加密,不让外人轻易访问,更不允许不知道密码的人把自己的服务注册到服务注册中心.

第一步:引入依赖

        
            org.springframework.boot
            spring-boot-starter-security
        

第二步:在yml中配置账号和密码

spring:
  security:
    user:
      name: laowang  #填你自己的,不要写中文
      password:123 #填你自己的

然后启动项目,访问http://localhost:8761,一看果然配置好了,需要输入账号和密码才能访问

【spring-cloud】spring-cloud-从入门到高可用-下_第1张图片

登录后发现跟之前没啥差别,是的,原以为这样就算配置好了,但新版本的spring-security里却有坑,坑了我好久下面会介绍.CSRF(Cross-site request forgery)跨站请求伪造

配置好之后,服务的注册也需要做相应的修改,具体是将yml中的defaultZone格式改为:

http://账号:密码@发现中心的地址,例如:

defaultZone: http://laowang:123@localhost:8761/eureka,http://laowang:123@localhost:8762/eureka

这样就配置好了,但是发现服务怎么都注册不上去,不停的报错...因为我用的是当前最新的SR1版本,网上几乎搜不到这个版本相关的参考资料,除了spring官网,其他地方很难找到可以帮助的文档,耗费了近一个下午总算是找到了点有用的东西,原因是新版的spring-security默认开启了防止CSRF(Cross-site request forgery)跨站请求伪造,防止csrf攻击,开启了这个会把服务注册拒之门外,自己人也被拦截了,所以无法注册,解决办法是添加配置类:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();//关闭csrf
        super.configure(http);
    }
}

添加后重新启动项目即可完成服务的注册了,至此才算是配置完成.

 

三:spring-cloud最新版本SR1中踩到的坑总结:

1.csrf,如上所述.

2.dashboard配置好了,访问可以正常访问,但不能监控服务,显示Loding或unable.

【spring-cloud】spring-cloud-从入门到高可用-下_第2张图片

查了一下午,最后是在一个国外的网站上找到解决办法的,在启动类里添加配置Bean,如下:

@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
@EnableFeignClients
@EnableHystrixDashboard
public class YltOutpatientApplication {
    @Bean
    public ServletRegistrationBean getServlet() {
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }

    public static void main(String[] args) {
        SpringApplication.run(YltOutpatientApplication.class, args);
    }
}

这样就可以解决了...

3.zipkin中无服务追踪信息,zipkin是配好了,但你发现zipkin中并没有任何服务调用追踪相关的信息,原因是你没有指定服务追踪发送消息的方式,新版本中一共有3种服务追踪链路发送方式,一种是web,一种mq,一种sql,你必须在需要追踪的服务的yml中显示指定它,才能将追踪信息发送到zipkin中,否则就无法查看任何调用信息,例如:

spring:  
  zipkin:
    base-url: http://localhost:9411/
    service:
      name: test
    enabled: true
    sender:
      type: web
  sleuth:
    sampler:
      probability: 1

4.配置中心无法自动从git拉取配置,在一切都配的没有问题时,依旧不能拉取配置,了解一下才发现是因为spring-cloud只支持github,尚不支持从coding.net这样的仓库拉取配置,国内目前新版本支持码云,在码云中配置webhook才有效.

5.Hystrix超时服务降级问题,这个问题藏的比较深,国内外网站都去搜过了,至今没找到解决办法,所以这里简单描述下:

A服务调用B服务,我故意让B服务的线程休眠2秒钟,然后触发Hystrix服务降级,Hystrix的默认服务调用降级时间为1秒,如果服务之间的相互调用时间超过1秒就会触发降级,但这个时间是可以修改的,在SR1版本中无论我怎样修改这个时间,服务都会被降级,当我把这个时间修改到3秒甚至5秒时,服务仍会被降级,不同的是,我修改了服务降级时间后,A服务在真实的调用完B服务之后才触发降级,原来降级仅需要1.01秒左右就被触发了,现在我改完之后变成了2.35秒左右才被降级,不知道这是cloud官方有意这样做还是尚未修复的bug,以后再去研究,暂时用不到.

可能还有一些尚未踩到过的坑,以上便是我在spring-cloud的学习和搭建中遇到的所有坑,版本是目前最新版:Finchley.SR1,如果介意踩坑的话可以用一些旧点的版本,spring-cloud的更新实在是太快了,去年到今年迭代了好多个版本,所以还是推荐用新的版本,就算有坑,从这些坑里慢慢爬出来,你会有更多的成长.

你可能感兴趣的