3.2.2 Service Mesh之服务注册和发现模式
在微服务架构设计中,服务注册和发现模式是一个非常典型的架构模式。我们在服务化架构模式中也提到过服务注册和服务发现的模式。这一模式的典型代表是Java开发者非常了解的Spring Cloud架构体。Spring Cloud典型架构如图3-5所示。
图3-5 Spring Cloud典型架构
每个微服务应用启动后,都会向服务注册中心进行注册。服务注册中心产品包括Eureka、Console、Etcd等。注册的信息包括微服务的应用名、对外服务的IP地址和端口号、应用健康度检查HTTP URL,还有一些开发者自行设置的tag信息等。通常,我们不用考虑如何进行服务注册这些琐事,在Spring Boot应用中,只需要添加对应服务注册中心的starter依赖,然后设置连接地址即可。具体的服务注册对开发者来说完全是透明的。
在Spring Cloud架构下,微服务的通信只需要添加对应的@EnableDiscoveryClient Annotation,让应用连接到Registry Server,然后应用向Registry Server查询相关的服务(这个过程就是我们所说的服务自动发现),最后创建一个具有负载均衡能力的RestTemplate,以便访问其他的HTTP REST服务。示例代码如下:
@SpringBootApplication @EnableDiscoveryClient public class MicroApp1 { @LoadBalanced @Bean RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(MicroApp1.class, args); } }
调用其他应用的HTTP REST服务也非常简单,我们只需要将应用名作为HTTP URL的主机名,服务的自动发现机制会自动完成应用到具体IP和服务端口号的替换,这个过程对开发人员来说是透明的。示例代码如下:
@Controller public class HelloWebClientController { @Autowired private RestTemplate restTemplate; @GetMapping("/") public String handleRequest(Model model) { //accessing hello-service HelloObject helloObject = restTemplate.getForObject("http://hello-service/hello", HelloObject.class); model.addAttribute("msg", helloObject.getMessage()); model.addAttribute("time", LocalDateTime.now()); return "hello-page"; } }
上面只提到了一些HTTP REST服务的例子,其他类似的RPC服务调用完全可以复用服务发现的机制,实现服务的透明调用和负载均衡。
上述微服务之间的通信方案,对于同一数据中心内部应用之间的通信也非常适合。通过服务发现机制,应用之间可以直接连接并完成服务的调用。针对外部接入的场景,Spring Cloud还提供了Gateway方案,即应用无须接入Registry Server,而是通过Cloud Gateway调用服务,由Cloud Gateway负责与Registry Server的对接,完成服务发现和对应的服务调用。这一机制非常适合瘦客户端和多语言接入场景,唯一的要求是要能访问HTTP REST服务,不需要考虑服务发现、负载均衡等逻辑,因为Cloud Gateway会帮助外部应用解决这些问题。
另外,Spring Cloud还提供了其他相关服务,例如与Zipkin整合解决服务跟踪问题、与MicroMeter整合解决Metrics采集问题、与Resilience4J等整合实现断路保护(Circuit Breaker)功能,这些服务基本涵盖了服务治理的方方面面。
自2015年年初Spring Cloud发布1.0.0版本以来,基于Spring Cloud方案的Service Mesh涉及的服务一直在不断演进,并在很多公司得到广泛采用。Spring Cloud如今已经非常成熟和稳定,完全满足Service Mesh的各种要求。阿里巴巴基于阿里云的基础设施服务,推出了Spring Cloud Alibaba,目的是基于Spring Cloud的生态和规范更好地为开发人员服务。关于Spring Cloud Alibaba的更多详情请参考https://spring-cloud-alibaba-group.github.io/github-pages/hoxton/en-us/index.html。
这里可能会有读者疑惑,Spring Cloud为何不宣传或标榜为Service Mesh产品?首先,Spring Cloud实际发布于2015年年初,早于2017年4月提出的Service Mesh概念;其次,Spring Cloud覆盖的范围更广,远远超出了Service Mesh所涉及的范围,如安全认证、配置服务、流式数据处理、Cloud Function、Cloud Task、ZooKeeper和Vault对接,当然还包括与阿里云、亚马逊AWS、谷歌云、微软Azure等知名云服务的对接,从而降低了接入各种云服务的成本。
当然,Spring Cloud也存在一些不足之处,尤其是在多语言支持上。如果技术栈基于JVM,选择的编程语言是Java、Kotlin、Scala等JVM生态的语言,那么Spring Cloud方案就是非常不错的选择。但如果系统的核心编程语言不是Java,而是Node.js、Go、Python或者Rust等语言,Spring Cloud方案就不太适合了,毕竟要使用其他编程语言开发出类似的体系,工作量非常大。但这也不是完全不可能的,如Go的Micro(网址为https://github.com/micro/micro),其设计思想就与Spring Cloud非常类似。