一、微服务特点:
一个简单的微服务工程一般会有三种角色:
- 注册中心 在注册中心维护了服务列表
- 服务提供方 服务提供方启动的时候会把自己注册到注册中心
- 服务消费方 服务消费方启动的时候,把获取注册中心的服务列表,然后调用的时候从这个服务列表中选择某一个去调用。
微服务工程的特点:
- 扩展灵活
- 每个应用都规模不大
- 服务边界清晰,各司其职
- 打包应用变多,往往需要借助 CI 持续集成工具
二、简单的微服务工程的搭建
1、创建主工程
我们采用 Maven 的多 Module 结构来构建工程。整体结构如下:
- 创建springcloud的主工程,用来管理版本。主工程pom.xml 中 jar 包依赖如下:
<!--springcloud 工程是基于 springboot 工程的-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.5.RELEASE</version>
</parent>
<!--使用 dependencyManagement 来管理 Spring Cloud 的版本-->
<dependencyManagement>
<dependencies>
<!--在主工程中使用 dependencyManagement 声明 Spring Cloud 的版本,
这样工程内的 Module 中引入 Spring Cloud 组件依赖时,就不必在声明组件的版本信息
保证 Spring Cloud 各个组件一致性-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR12</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2、注册中心搭建
Springcloud 中,我们选择 eureka 作为注册中心。
- 在主工程下创建一个名为 springcloud-eureka 的 Module 作为服务注册中心,并在其 pom.xml 中引入以下依赖。
<!--Eureka 服务端启动器导入-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
- 在 springcloud-eureka 的resouces 目录下,添加配置文件 application.yml,配置内容:
server:
port: 8763 # 服务端口号
eureka:
instance:
hostname: localhost #eureka服务端的实例名称,
client:
register-with-eureka: false #是否注册到eureka 不向注册中心注册自己
fetch-registry: false #是否从eureka中拉取注册信息 自己就是注册中心,负责维护实例,不需要检索实例。
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #暴露eureka服务的地址
server:
#自我保护模式,当出现出现网络分区、eureka在短时间内丢失过多客户端时,会进入自我保护模式,即一个服务长时间没有发送心跳,eureka也不会将其删除,默认为true
enable-self-preservation: true
#Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来
renewal-percent-threshold: 0.85
#eureka server清理无效节点的时间间隔,默认60000毫秒,即60秒
eviction-interval-timer-in-ms: 60000
- 启动类如下:
@SpringBootApplication
@EnableEurekaServer //开启Eureka服务注册功能
public class EurekApplication {
public static void main(String[] args) {
SpringApplication.run(EurekApplication.class,args);
}
}
- 启动后可以访问服务注册中心主页。地址 "http://localhost:8763/"
2、服务提供方
服务提供方要把服务注册到eureka服务端,所以服务提供方就是 eureka 的客户端,所以需要导入 eureka 客户端的JAR包。
- 在主工程下创建一个名为 springcloud-provider 的 Module,在其 pom.xml 中引入以下依赖
<!--web 依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引入 Eureka Client 的依赖,将服务注册到 Eureka Server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- application.yml配置文件如下:
spring:
application:
name: provider #微服务名称,对外暴漏的微服务名称, 重要
server:
port: 8081 # 服务端口号
eureka:
client: #将客户端注册到 eureka 服务列表内
service-url:
defaultZone: http://localhost:8763/eureka/ #注册中心地址
- 启动类
@SpringBootApplication
@EnableEurekaClient /// 开启客户端功能,本服务会注册到 Eureka Server 注册中心中
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class,args);
}
}
- 我们还需要提供一个接口“/queryuser”实现具体业务,让后面的服务消费方来调用
@RestController
@RequestMapping("/")
public class UserController {
@RequestMapping("/queryuser")
public String queryUser(){
/*业务逻辑*/
return "服务提供者查到用户两条";
}
}
3、服务消费方
pom 和属性配置文件基本上差不多,消费要负责调用服务提供方,所以需要调用客户端。
服务调用的时候就根据服务提供方的服务名称来调用的。
- 在主工程下创建一个名为 springcloud-consumer 的 Module,在其 pom.xml 中引入以下依赖
<!--web 依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引入 Eureka Client 的依赖,将服务注册到 Eureka Server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- application.yml配置文件如下:
spring:
application:
name: consumer #微服务名称,对外暴漏的微服务名称, 重要
server:
port: 8082 # 服务端口号
eureka:
client: #将客户端注册到 eureka 服务列表内
service-url:
defaultZone: http://localhost:8763/eureka/ #注册中心地址
- 启动类
@SpringBootApplication
@EnableEurekaClient
public class ConsumerApplication {
@Bean
@LoadBalanced // 负责均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class,args);
}
}
- 服务调用:
服务提供方的名称,再加上服务提供方的接口名就可以完成调用了
@Controller
@RequestMapping("/test")
public class TestController {
public static final String SERVERNAME = "provider"; //服务提供方名称
@Autowired
RestTemplate restTemplate;
// http//127.0.0.1:8082/test/get
@RequestMapping("/get")
@ResponseBody
public String test(){
// 服务提供方的名称 provider ,再加上服务提供方的接口名queryuser 就可以完成调用了
String result = restTemplate.getForObject("http://" + SERVERNAME + "/queryuser", String.class);
System.out.println(result);
return result;
}
}
4、启动
- 先启动注册中心后启动其他服务。
服务提供方和服务消费启动的时候都会往服务注册中心注册服务,eureka 服务端也可以通过
界面查看到服务注册情况:
- 我们调用消费端的测试路径,可看到已经从服务提供方返回数据。