Spring Cloud构建微服务项目
组件/服务简介
-
Spring Cloud
Spring Cloud 是一系列有序框架的集合,是基于Spring Boot的特性构建的分布式系统解决框架,提供服务发现与注册,配置中心,消息总线,负载均衡,断路器,数据监控等服务,通过Spring Boot的方式,可以实现一键启动,和部署,进而搭建了一套Java生态的微服务解决方案。
图示:
-
Eureka
Eureka 是 Netflix 的一个子模块,也是核心模块之一,它是一个基于 Rest 的服务,用于定位服务,服务注册和发现,以实现云端中间层服务发现和故障转移。
Eureka的服务注册和发现只需要使用服务的标识符,就可以访问到服务,而不需要修改服务调用的配置文件了,功能类似于 Zookeeper、Consul等服务,服务提供者【也可以是消费者】和服务消费者同时在Eureka-Server注册服务信息,当服务消费者需要远程调用服务提供者的服务时,可以直接通过在Eureka-Server注册是服务名完成服务调用,避免了url的依赖更新操作。
核心组件
- Eureka Server:提供服务注册服务,EurekaServer 中的服务注册表中将会存储所有可用服务节点的信息
- Eureka Client:是一个 Java 客户端,同时也具备一个内置的、集成轮询 (round-robin) 负载算法的负载均衡器
Eureka Client服务构成:
- Service Provider 服务提供方将自身服务注册到 Eureka,从而使服务消费方能够找到
- Service Consumer 服务消费方从 Eureka 获取注册服务列表,从而能够消费服务
图示:
-
Feign
Feign是声明式,模板化的web service客户端,功能类似controller调用service,它让微服务之间的调用变得更简单,通常与Eureka配合使用,基于服务发现实现高可用的远程服务的调用。
图示:
一、新建父级项目—所有微服务的公共父
二、精简父级项目-删减
-
删除src目录
-
保留配置pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.2</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>microservice</artifactId> <version>0.0.1-SNAPSHOT</version> <name>microservice</name> <description>microservice</description> <packaging>pom</packaging> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
三、新建微服务,集成Eureka-server服务注册中心
-
右键microservice新建一个Module
-
项目名称:eureka-server 服务组件选择
-
导入父级项目坐标
<parent> <groupId>com.example</groupId> <artifactId>microservice</artifactId> <version>0.0.1-SNAPSHOT</version> </parent>
-
更新配置文【application.yml】
server: port: 8001 eureka: hostname: localhost #暴露eureka服务的地址 client: serviceUrl: defaultZone: http://${eureka.hostname}:${server.port}/eureka/ #是否注册到eureka registerWithEureka: false #是否从eureka中拉取注册信息 fetchRegistry: false # 关闭自我保护 server: enable-self-preservation: true #清除无效节点,时间间隔为10秒 eviction-interval-timer-in-ms: 1000
四、新建微服务,集成Eureka-client客户端服务
-
4.1、新建服务提供项目- manager-server
-
右键microservice新建一个Module
-
项目名称:manager-server 服务组件选择:Spring Web和Eureka Discovery Client
-
导入父级坐标
<parent> <groupId>com.example</groupId> <artifactId>microservice</artifactId> <version>0.0.1-SNAPSHOT</version> </parent>
-
更新配置文件【application.yml】
#自定义微服务名称 spring: application: name: manager-server #端口 server: port: 8090 #根据刚才定义的注册中心的对外暴露的地址填写。 eureka: client: serviceUrl: defaultZone: http://localhost:8001/eureka/ #每隔3秒拉取最新的注册列表(默认30秒) registry-fetch-interval-seconds: 3 #心跳间隔时间为3秒(默认30秒) instance: lease-renewal-interval-in-seconds: 3 #6秒没有接收到心跳则剔除微服务(默认90秒) lease-expiration-duration-in-seconds: 6
-
编写测试Controller【本文仅仅是示例,因此不使用mybatis进行实践模拟】
@RestController @RequestMapping("/api") public class TestController { @GetMapping(value = "/hello") public String hello(){ return "hello world!"; } }
-
启动类开启服务注册
@EnableEurekaClient @SpringBootApplication public class ManagerServerApplication { public static void main(String[] args) { SpringApplication.run(ManagerServerApplication.class, args); } }
-
-
4.2、新建服务消费服务- consumer-service
-
配置文件更新前基本步骤和manager-server一致
-
更新配置文件
#自定义微服务名称 spring: application: name: consumer-service #端口 server: port: 8082 #根据刚才定义的注册中心的对外暴露的地址填写。 eureka: client: serviceUrl: defaultZone: http://localhost:8001/eureka/ fetch-registry: true #每隔3秒拉取最新的注册列表(默认30秒) registry-fetch-interval-seconds: 3 #心跳间隔时间为3秒(默认30秒) instance: lease-renewal-interval-in-seconds: 3 #6秒没有接收到心跳则剔除微服务(默认90秒) lease-expiration-duration-in-seconds: 6 ribbon: eureka: enabled: true
-
启动类开启服务注册
@SpringBootApplication @EnableEurekaClient public class ConsumerServiceApplication { @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(ConsumerServiceApplication.class, args); } }
-
基于restTemplate远程调用服务【使用服务名】
-
controller
@RestController @RequestMapping("/api") public class TestController { @Resource private UserService userService; @GetMapping(value = "/getHello") public String consume(){ return userService.fun(); } }
-
service
public interface UserService { public String fun(); }
// 实现类 @Service public class UserServiceImpl implements UserService { public static String SERVICE_NAME = "manager-server"; @Autowired private RestTemplate restTemplate; @Override public String fun() { //简单演示get和post请求 String getFun = restTemplate.getForObject("http://" + SERVICE_NAME + "/api/hello", String.class); return getFun+" "; } }
-
-
-
4.3、引入Feign - 远程调用组件【ribbon-负载均衡可以自行测试】
-
consumer-service服务引入Feign
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
-
启动类开启注解
@SpringBootApplication @EnableFeignClients @EnableEurekaClient public class ConsumerServiceApplication { @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(ConsumerServiceApplication.class, args); } }
-
编写service
@FeignClient(value = "manager-server", name = "manager-server") public interface FeignClientInterface { @RequestMapping(value = "/api/hello",method = RequestMethod.GET) public String hello(); }
-
编写controller
@RestController @RequestMapping(value = "/api") public class FeignController { @Resource private FeignClientInterface feignClientInterface = null; @GetMapping("/rpc/hello") public String getDate() { return feignClientInterface.hello(); } }
-
五、测试效果
-
项目服务如图【多余组件请忽略】:
-
Eureka-server注册中心如图
-
服务端本地调用如图
-
消费端远程调用如图
-
基于restTemplate
-
引入Feign
-