本文从时下流行的微服务架构技术栈知识出发,结合Spring Cloud Alibaba提供微服务开发的⼀站式解决⽅案。此项⽬包含开发分布式应⽤微服务的必需组件,⽅便开发者通过Spring Cloud编程模型轻松使⽤这些组件来开发分布式应⽤服务。依托Spring Cloud Alibaba,您只需要添加⼀些注解和少量配置,就可以将Spring Cloud应⽤接⼊阿⾥微服务解决⽅案,通过阿⾥中间件来迅速搭建分布式应⽤系统。
本文主要以示例与源码结合的方式来帮助读者更好的理解这些组件的使用方法和运行原理。
以微服务分布式架构应用业务场景作为实践案例,循序渐进阐述Spring Boot、Nacos、Spring Cloud Ribbon、Spring Cloud Feign框架实用技术,讲述企业级Spring Cloud Alibaba开发技术栈知识。
在本文中,会讲到如下内容:
1、微服务基础知识
2、微服务构建:Spring Boot
3、服务治理:Spring Cloud Alibaba Nacos
4、客户端负载均衡:Spring Cloud Ribbon
5、声明式服务调用:Spring Cloud Feign
6、微服务实战案例
适合人:本篇文章是来自一线开发者的实战经验总结,对微服务分布式架构开发、设计感兴趣的所有技术人员。
一、微服务基础知识
1、微服务架构
微服务是系统架构上的一种设计风格,它的主旨是将一个原本独立的系统拆分成多个小型服务,这些小型服务都在各自独立的进程中运行,服务之间通过基于HTTP的RESTful API进行通信协作。被拆分成的每一个小型服务都围绕着系统中的某一项或一些耦合度较高的业务功能进行构建,并且每个服务都维护着自身的数据存储、业务开发、自动化测试案例以及独立部署机制。由于有了轻量级的通信协作基础,所以这些微服务可以使用不同的语言来编写。
二、微服务构建:Spring Boot
构建微服务的基础框架Spring Boot,由于Spring Cloud的构建基于Spring Boot实现。使用Spring Boot 的目的除了它是Spring Cloud的基础之外,也由于其自身的各项优点,如自动化配置、快速开发、轻松部署等,非常适合用作微服务架构中各项具体微服务的开发框架。
在项目依赖dependencies配置中,包含了下面两项。
1)spring-boot-starter-web: 全栈Web开发模块,包含嵌入式Tomcat、Spring MVC。
2)spring-boot-starter-test: 通用测试模块,包含JUnit、Hamcrest、 Mockito。
这里所引用的web和test模块,在Spring Boot生态中被称为Starter POMs。Starter POMs是一系列轻便的依赖包。开发者在使用和整合模块时,不必再去搜寻样例代码中的依赖配置来复制使用,只需要引入对应的模块包即可。
父项目parent配置指定为spring-boot-starter-parent的2.3.2版本,该父项目中定义了Spring Boot版本的基础依赖以及一些默认配置内容,比如,配置文件application.properties的位置等。
项目构建的build部分,引入了Spring Boot的Maven插件,该插件非常实用,可以帮助我们方便地启停应用,这样在开发时就不用每次去主类或是打包成jar来运行微服务,只需要通过mvn spring-boot:run命令就可以快速启动Spring Boot应用。
本文实战案例采用maven 3.5、Java 1.8、Spring Boot 2.3调试通过。
三、服务治理:Spring Cloud Alibaba Nacos
Spring Cloud Alibaba通过为Nacos增加了Spring Boot风格的自动化配置,我们只需通过简单引入依赖和注解配置就能让Spring Boot构建的微服务应用轻松地与Nacos服务治理体系进行整合。
服务治理可以说是微服务架构中最为核心和基础的模块,它主要用来实现各个微服务实例的自动化注册与发现。
服务注册:在服务治理框架中,通常都会构建一个注册中心,每个服务单元向注册中心登记自己提供的服务,将主机与端口号、版本号、通信协议等一些附加信息告知注册中心,注册中心按服务名分类组织服务清单。比如,我们有两个提供服务A的进程分别运行于192.168.0.100:8000和192.168.0.101:8000位置上,另外还有两个提供服务B的进程分别运行于192.168.0.100:9000 、192.168.0.101:9000位置上。当这些进程均启动,并向注册中心注册自己的服务之后,注册中心就会维护一个服务清单。另外,服务注册中心还需要以心跳的方式去监测清单中的服务是否可用,若不可用需要从服务清单中剔除,达到排除故障服务的效果。
服务发现:由于在服务治理框架下运作,服务间的调用不再通过指定具体的实例地址来实现,而是通过向服务名发起请求调用实现。所以,服务调用方在调用服务提供方接口的时候,并不知道具体的服务实例位置。因此,调用方需要向服务注册中心咨询服务,并获取所有服务的实例清单,以实现对具体服务实例的访问。比如,现有服务C希望调用服务A, 服务C就需要向注册中心发起咨询服务请求,服务注册
中心就会将服务A的位置清单返回给服务C, 如按上例服务A的情况,C便获得了服务A的两个可用位置192.168.0.100:8000和192.168.0.101:8000。当服务C要发起调用的时候,便从该清单中以某种轮询策略取出一个位置来进行服务调用,这就是后续我们将会介绍的客户端负载均衡。
Nacos支持几乎所有主流类型的“服务”的发现、配置和管理:
1)gRPC&Dubbo RPC Service
2)Spring Cloud RESTful Service
3)Kubernetes Service
Nacos支持基于DNS和基于RPC的服务发现。
Nacos提供对服务的实时的健康检查,阻止向不健康的主机或服务实例发送请求。
动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。
动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。
配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。
动态DNS服务支持权重路由,让您更容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单DNS解析服务。
Nacos能让您从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略、服务的SLA以及最首要的metrics统计数据。
四、客户端负载均衡:Spring Cloud Ribbon
Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模板请求自动转换成客户端负载均衡的服务调用。Spring Cloud Ribbon虽然只是一个工具类框架,它不像服务注册中心、配置中心、API网关那样需要独立部署,但是它几乎存在于每一个Spring Cloud构建的微服务和基础设施中。因为微服务间的调用,API网关的请求转发等内容实际上都是通过Ribbon来实现的,包括后续我们将要介绍的Feign, 它也是基于Ribbon实现的工具。所以,对Spring Cloud Ribbon的理解和使用,对于我们使用Spring Cloud 来构建微服务非常重要。
通过Spring Cloud Ribbon的封装,我们在微服务架构中使用客户端负载均衡调用非常简单,只需要如下两步:
1)服务提供者只需要启动多个服务实例并注册到一个注册中心或是多个相关联的服务注册中心。
2)服务消费者直接通过调用被@LoadBalanced注解修饰过的RestTemplate来实现面向服务的接口调用。这样,我们就可以将服务提供者的高可用以及服务消费者的负载均衡调用一起实现了。
五、声明式服务调用:Spring Cloud Feign
Spring Cloud Feign基于Netflix Feign实现,整合了Spring Cloud Ribbon与Spring Cloud Hystrix, 除了提供这两者的强大功能之外,它还提供了一种声明式的Web服务客户端定义方式。
我们在使用Spring Cloud Ribbon时,通常都会利用它对RestTemplate的请求拦截来实现对依赖服务的接口调用,而RestTemplate已经实现了对HTTP请求的封装处理,形成了一套模板化的调用方法。在实际开发中,由于对服务依赖的调用可能不止于一处,往往一个接口会被多处调用,所以我们通常都会针对各个微服务自行封装一些客户端类来包装这些依赖服务的调用。这个时候我们会发现,由于RestTemplate的封装,几乎每一个调用都是简单的模板化内容。综合上述这些情况,Spring Cloud Feign在此基础上做了进一步封装,由它来帮助我们定义和实现依赖服务接口的定义。在Spring Cloud Feign的实现下,我们只需创建一个接口并用注解的方式来配置它,即可完成对服务提供方的接口绑定,简化了在使用Spring Cloud Ribbon时自行封装服务调用客户端的开发量。Spring Cloud Feign具备可插拔的注解支持,包括Feign注解和 JAX-RS注解。同时,为了适应Spring的广大用户,它在Netflix Fe
ign 的基础上扩展了对Spring MVC的注解支待。这对于习惯于Spring MVC的开发者来说,无疑是一个好消息,因为这样可以大大减少学习使用它的成本。另外,对于Feign自身的一些主要组件,比如编码器和解码器等,它也以可插拔的方式提供,在有需求的时候我们可以方便地扩展和替换它们。
六、微服务实战案例
实战案例模拟消费者微服务调⽤提供者微服务,消费者微服务和提供者微服务都注册到Nacos,以及后续从Nacos读取配置属性。
1、创建⽗⼯程
打开当前工程下的Maven配置文件l,看一下生成的项目都引入了哪些依赖来构建Spring Boot 工程,⽗⼯程统⼀管理spring boot、spring cloud和spring cloud alibaba版本号。内容大致如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns=".../POM/4.0.0"
xmlns:xsi=".../2001/XMLSchema-instance"
xsi:schemaLocation=".../POM/4.0.0 .../xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bjwykj</groupId>
<artifactId>spring-cloud-alibaba</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>bjwykj-common</module>
<module>bjwykj-provider</module>
<module>bjwykj-consumer</module>
</modules>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<alibaba-cloud.version>2.2.5.RELEASE</alibaba-cloud.version>
<springcloud.version>Hoxton.SR8</springcloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${springcloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${alibaba-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apachemons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、创建公共⼯程
提供消费者微服务和提供者微服务业务都需要的公共实体类。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns=".../POM/4.0.0"
xmlns:xsi=".../2001/XMLSchema-instance"
xsi:schemaLocation=".../POM/4.0.0 .../xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-alibaba</artifactId>
<groupId>com.bjwykj</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>bjwykj-common</artifactId>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
1)实体类CommonResult
package com.ity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult<T>
{
private Integer code;
private String message;
private T data;
public CommonResult(Integer code,String message)
{
this(code,message,null);
}
}
2)实体类Provider
package com.ity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructormvc实例
public class Provider implements Serializable
{
private Long id;
private String serial;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论