logo

地址:深圳南山区大冲国际中心21楼

联系我们 : contact@wise2c.com

产品支持 : service@wise2c.com

售前咨询 : sales@wise2c.com

电话: +86 (755) 33268246

粤ICP备16049363号

Build MicroService With Spring Cloud And Rancher

深圳睿云智合科技有限公司 > 睿云新闻  > Build MicroService With Spring Cloud And Rancher

Build MicroService With Spring Cloud And Rancher

郑云龙

分享人:郑云龙

时间:2016720

 

睿云智合持续交付产品负责人,在敏捷和DevOps领域有丰富经验的实践,过去作为敏捷和DevOps技术教练向多家大型企业提供咨询和培训服务。

Build MicroService With Spring Cloud And Rancher

 

 

1, Aganda

 

今天给大家分享的内容是:《Build MicroService With Spring Cloud And Rancher》主要内容:我们将演示如何通过Spring Cloud和Rancher构建一个具有弹性的微服务应用。并且在这个过程中当中我们主要遇到的问题,以及最后如何解决。

微服务应用

对于一个最简单的微服务应用而言,一个最基本的结构如上所示:

  • 我们需要一个服务发现和注册服务帮助我们管理和发现新的服务;
  • 当我们从一个单体应用到几个,几十个微服务时,服务的配置也成了一个非常棘手的问题,统一的配置管理必不可少;
  • 为了简化我们的客户端调用我们可能需要一个轻量级API Gateway来统一代理我们的所有请求,同时可以做统一的安全控制;
  • 同时在微服务下我们应该遵循Build For Failure的原则,当服务发生失败时我们能够隔离这些失败的服务,从而需要引入Circuit Breaker熔断器;
  • 除此之外,同一个服务可能有一个到多个实例,当我们访问服务时,我们还需要一个负载均衡器,帮助我们合理的分发我们的API请求。

 

2, Build MicroService With Spring Cloud

Build MicroService With Spring Cloud

 

而Spring Cloud项目正是帮助我们解决以上问题的利器,让我们可以更加专注于我们服务本身业务逻辑的开发,而将服务治理所需的工作都统统交给框架来完成。

  • Eureka提供了统一的服务发现和注册能力;
  • Ribbon和Hystrix则在服务和服务之间引入了负载均衡以及熔断的能力;
  • Zuul则作为一个轻量级的路由和代码服务让我们可以快速建立一个API Gateway的能力。

3, Service Discovery With Spring Cloud Netflix: Eureka

Service Discovery With Spring Cloud Netflix: Eureka

 

以Eureka提供的服务注册和发现能力为例,作为一个微服务实例,在启动时我们将会主动向Eureka Server进行注册。Eureka Server服务维护当前服务的实例列表以及状态健康检查。        而作为服务的使用者,我们首先需要向eureka server请求当前的服务实例,之后再将请求发送给API的真正提供者。

 

4, Client Side Load Balance: Ribbon

Client Side Load Balance: Ribbon

 

同时Spring Cloud的Ribbon项目还提供了一个客户端的负载均衡器,可以根据当前服务的运行状态来讲请求发送到适合的实例。

 

5, Quick Start Demo

Quick Start Demo

 

这里我们展示一下Spring Cloud是如何帮助我们快速搭建一个微服务架构的应用的。

Spring Cloud

这里我们以一个最简单的spring cloud应用为例,这里我们包含3个主要服务:Eureka Server, Hello Server以及Hello Client。

Eureka Server

首先基于Spring Boot我们可以@EnableEurekaServer可以快速创建一个EurekaServer的服务,基本不需要任何代码量。

Hello Server

同时我们基于Spring Boot创建另外一个项目Hello Sever,提供一个非常简单的API返回一串字符。在application.yml当中我们配置该服务的名称为HelloServer, 端口为7111,并且配置eureka server的地址,在应用启动时,将会主动注册服务相关信息。

Hello Client

同样我们建立一个Hello Client的微服务实例,这里唯一的区别是我们使用Spring Cloud的FeignClient声明了一个接口,该注解告诉Spring Cloud当调用HelloClient的hello方法时,需要向HelloServer的实例的”/”地址发送一个GET请求,并且返回结果是一个字符串。

同样的我们在application.yml文件中也配置了eureka相关的信息,为Hello Client建立一个Rest API,该API实际调用的是Hello Sever提供的服务。

ALL Server

依次启动Eureka Server, Hello Server, Hello Client. 我们得到了一个最简单的微服务架构的应用,我们将会得到如上的运行结果。当访问Hello Client的Rest API时,实际请求转发到了Hello Server并且得到相应的结果返回给用户。

How The Work?

这个是如何工作的呢? 我们简单解释一下,和刚才图一样:

1 Hello Server向Eureka Server进行注册名为HelloServer的服务实例。

2 Eureka Server得到请求后保存了HelloServer的实例列表信息(IP地址以及其他状态信息)。

3 Hello Client请求http://localhost:7211时,调用了HelloClient的hello()方法,该方法的@FeginClient(“HelloServer”)注解告诉Hello Client我们需要先向Eureka Server请求HelloServer的服务实例列表,之后再根据返回的实例列表将请求发送给HelloServer其中一个实例。

这里需要注意Spirng Cloud中的一个配置项eureka.instance.preferIpAddress默认情况下该配置为True. 表示Spring Cloud优先使用HelloServer注册的IP地址,如果访问不成功我们则使用HelloServer的名称作为默认的域名发送请求。同理当eureka.instance.preferIpAddress为false时,Spring Cloud则直接使用默认的spring.application.name也就是HelloServer作为域名发送请求。

 How The Work?

 

所以对于部署基于Spring Cloud的微服务应用时,我们对于网络环境的基本要求是:1, 各个服务实例能够访问eureka-server;

2, 各个服务实例之间能够通过IP地址或者DNS域名相互访问。

Back To Rancher

 

6, Rancher: A Complete Platform for Running Containers

 

Rancher作为一Production目标的容器管理平台,当然是我们去运行,管理和维护微服务的首选运行平台之一。        当我们把我们所有的服务制作为Dokcer镜像之后,我们可以通过docker-compose.yml来编排我们的服务,如上Client-Service以及Hello-Service都与Eureka相连,并且设置eureka的访问地址为eureka-server,与我们application.yml中配置的eureka url相一致。

通过Rancher启动docker-compose.yml之后,我们可以在eureka-server页面上看到相关的服务实例信息。

通过Rancher我们可以非常方便的对我们的微服务应用进行管理,同时提供scale相关的能力支持。         这个时候重新尝试访问我们的Server服务, 一切正常。得到了相应的API返回值。

 

我们再尝试访问我们的Client服务呢。。。出错了。。。

出错了

 

7, Rancher Network Service

 

我们来分析一下出错的原因:

首先我们的服务和服务是分布式部署在不同的Rancher Agent上的。Rancher使用managed network来完成跨主机的容器与容器之间的相互连接。同时Docker也有自己默认的的bridge network。 但是bridge network只能保证同一个Host上的容器是互通的。        而client以及server在启动时,获取的默认网络地址则是birdge network的ip地址。 所以当访问client的rest api时,client向eureka获取的IP地址是不可访问的,之后又尝试了spring.application.name也就是http://HelloServer:7111同样出错,因为HelloServer是没有任何DNS服务能够解析的。所以得到了我们的错误页面。如下图所示:

Rancher Network

再直观一点的情况如下图所示:

所以在该模式下,我们的各个服务虽然都能向eureka server注册相关信息,但是服务和服务之间是不能相互访问的。

服务和服务之间是不能相互访问

如何解决?

如何解决?

 

8, Rancher Internal DNS Services

 Rancher Internal DNS Services

 

首先:Rancher提供的内部DNS服务,在容器中我们可以通过<service_name>或者<service_name>.<stack_name>来访问其他的服务容器实例。

那么我们假如启动硬编码client以及server时设置hostname的配置,比如对于client 我们配置eureka.instance.hostname=client-service,对于server我们配置eureka.instance.hostname=hello-service。        这样当服务和服务之间相互访问时,则会使用我们配置的eureka.instance.hostname作为域名进行访问。        但是问题在于client-service和hello-service的名字实际上是和docker-compose相对应的。 如果docker-compose.yml修改了各个服务的名字。 那服务和服务之间同样是不可相互访问的。

 

9, Rancher Metadata Services

 

如何解决?

Rancher Metadata Services

Rancher Metadata Service. 通过metadata service我们可以通过使用HTTP API的方式来获取到我们的服务以及容器的所有信息。

举例来说,通过在容器内访问:http://rancher-metadata/latest/self/container/service_name我们便可以获取到该容器的server_name,除此之外,包括容器的健康状态,hostname,primary_ip以及其他等等信息我们都可以通过该方式来进行获取。

 

10, Solution And Summary

 Solution And Summary

 

        综合以上问题以及Rancher平台所提供的能力,在Dockerfile中我们使用单独的shell文件作为启动脚本,在该启动脚本中我们首先调用ranchermetadata service获取该containerservice_name, 并且将该service_name作为eureka.instance.hostname的值作为jar包的启动参数即可。

 Rancher平台

THANK YOU

 

 

 

在这个案例中,我们使用Spring Cloud快速搭建了一个简单应用。 同时利用Racnher提供的容器管理能力,以及DNS Service和Metadata Service解决在容器分布式部署状态下的一些主要问题。希望能对大家有一定的参考。

 

关于本次分享的源码已经发布在github:  https://github.com/yunlzheng/spring-cloud-with-rancher.git

No Comments

Post a Comment

Comment
Name
Email
Website