从Eureka入手聊聊Spring Cloud

(转载请注明作者和出处‘https://fourthringroad.com/’,请勿用于任何商业用途)

之前整理过spring bean管理和web mvc什么的,一直也想写一篇整理整理spring cloud的知识。

在Amazon工作时,搭建微服务有不少技术方案可供选择,Amazon内部有团队对Spring Framework做了一层封装和适配,也成为微服务搭建的选项之一。不过内部对spring别的产品使用较少,我想主要原因是内部存在同类产品,且针对Amazon的技术架构做了一些定制化,更灵活,onboard成本和难度也都控制的不错,所以就只是按需从spring产品中选择了一些纳入进来(当然可能也有商用版权的问题)。18年我所在的团队做的一个CMS系统,使用这个整合Spring Framework的框架搭建了一个Rest风格的服务后端。

在来到京东云后,接手的中间件服务配置中心和调度服务使用了springboot,spring framework和spring cloud,同时在跟应用方打交道过程中,发现90%的客户也都是用的spring全家桶在搭建微服务。

关于Spring团队和产品

从04年发布spring1.0到现在,spring也有快20年的历史了。公司从最早的Interface 21(后改名SpringSource),到12年被VMware收购,再到后来成立Pivotal接着独立上市。相关团队一直致力于java领域的开源开发。现在spring在行业内的流程程度不用赘述,大部分web开发也不用再参照臃肿的J2EE规范。

spring的相关产品也从最初的基础的spring framework发展出spring boot, spring data, spring cloud, spring security…link(https://spring.io/projects)。

关于Spring Cloud

关于Spring Cloud,我理解其实就是将搭建分布式系统中遇到的问题抽象为一些固定模式(pattern),譬如分布式系统如何进行配置管理,服务发现,服务熔断,负载均衡等等。在此基础上给每个模式提供实现的boiler plate。

Boiler Plate类似Template,但是又有区别,template可以理解成参数化的框架,来引导工程师完成系统搭建;但是Boiler Plate在框架上还包括了实现;基本上Spring Cloud的模块我们拿来就可以直接部署,有一个词非常适合形容-开箱即用(out of box )。

题外话,在亚马逊工作的时候boiler plate,out of box都是常见词汇,从侧面也印证了,给用户提供服务时的易用性(容易onboard)是非常重要的考量标准。

spring cloud也跟各个大的云服务厂商有合作,针对不同的托管服务有定制化的功能,譬如针对AWS的定制化:https://spring.io/projects/spring-cloud-aws

先来看看下面这个demo

利用Eureka实现服务发现

云原生的微服务体系里面有一个重要的原则:铭记所有都是不断变化的。在这种背景下,应该避免所有硬编码的服务地址和端口,于是便有了服务发现的需求。

服务发现本身可抽象成一个数据存储服务,用来注册其他服务的信息,并提供查询功能,Eureka就是这样一个服务;从另一个方面讲,可以提供数据存储查询的服务都具备提供服务发现的能力;事实也是这样,ZK和Consul也可以提供类似服务,Spring Cloud也兼容这两种底层实现。

当然,在所有服务中,也都至少要保留‘服务发现服务’的硬编码地址,同时另一个缺点是这给请求增加了一个额外访问,也给系统增加了一个single point of failure;

首先是如何搭建Eureka这个拆箱即用的服务:

@EnableEurekaServer
@SpringBootApplication
public class EurekaTestServerApplication {
	public static void main(String[] args) {
		SpringApplication.run(EurekaTestServerApplication.class, args);
	}
}

配置:

server:
  port: 8761

eureka:
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl: #Eureka集群配置,单机配置自己,默认8761
      defaultZone: http://localhost:8761/eureka/

上面就是所有需要的代码。

启动并注册两个服务

Service-1

@EnableDiscoveryClient
//@EnableEurekaClient
@SpringBootApplication
public class EurekaTestClientApplication {

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

}

需要说明@EnableDiscoveryClient相比于@EnableEurekaClient可以兼容更多底层实现。

配置

server:
  port: 8090

spring:
  application:
    name: Service-1

eureka:
  client:
    registerWithEureka: true
    fetchRegistry: true
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    instance‐id: ${spring.application.name}

在Eureka的管理界面上就可以看到这两个服务的信息了:

上面的过程可以很好的解释了,

为什么使用Spring Cloud

当工程师需要构建云原生应用时,会发现自己需要在整套分布式系统中实现以下功能:

  • 配置管理
  • 服务发现
  • CircuitBreaker
  • 路由和消息通信(Routing and messaging)
  • API网关
  • 分布式追踪

等等

当你在FAANG这样的公司工作的时候,你可能发现有足够的底层服务提供上述功能,而且你可以用很小的代价就将其集成进来。但是事实上,有更多的公司不具备这样的条件,而是需要工程师重复的构造这些轮子。于是spring cloud就将这些功能做了上层抽象,并提供了相应的,非常容易集成的,解决方案,

  • 配置管理:springconfig,可以与Git,SVN,FS或DB结合来管理配置
  • 服务发现: Eureka, Zookeeper, Consul
  • CircuitBreaker:Hystrix
  • 路由和消息通信(Routing and messaging):
    • Routing and LB:Ribbon(实现client side LB) & Feign
    • Messaging:: RabbitMQ or Kafka
  • API网关:Zuul/Spring Cloud Gateway
  • 分布式追踪:Spring Cloud Sleuth / Zipkin

Spring Cloud的组件在设计时就已经考虑了云原生应用的特性:跨故障域,动态,高可用,高拓展…所以用户可以将设计的重心放在实现业务的组件上面。

利用OpenFeign进行服务间通信

接着上面的demo,当我启动两个服务之后,服务2对服务1的调用流程就是:

  • 服务2用注册中心client向注册中心发起请求:查找服务1地址
  • 服务2用远程调用client向服务1发起调用请求。

假设服务1对外暴露的接口为

@RestController
public class ServiceController {
    @GetMapping("/ping")
    public String ping() {
        return "service started.";
    }
}

引入Spring Cloud的服务间通信的组件OpenFeign后的实现代码为:

//定义访问Service-1的client与Rest接口的映射
@FeignClient("Service-1")
public interface Service1Client {
    @GetMapping("/ping")
    public String ping();
}

//注入
@Autowired
private Service1Client service1Client;

//使用
Object result = service1Client.ping();

代码非常简洁,启动和初始化过程几乎都被隐藏,用户只需要定义方法映射以及执行调用。同时Feign Client的底层还利用了ribbon,所以具备客户端负载均衡的能力。

这是使用Spring Cloud生态的另一个好处:它不仅仅功能完善,不同组件之间也能够很好的配合衔接。用户能够以非常小的代价集成一个新的功能模块。

此条目发表在spring相关分类目录。将固定链接加入收藏夹。

从Eureka入手聊聊Spring Cloud》有2条回应

  1. Robertanoke说:

    Арматура диаметром 32 мм, изготовленная из стали марки А500С, является одним из самых востребованных видов металлопроката в строительстве. Она применяется при возведении фундаментов, армировании стен и перемычек. https://armatura32.ru

发表评论

您的电子邮箱地址不会被公开。