此次博客将简单描述如何在使用SpringCloud框架创建的微服务项目中进行微服务的互相调用。
一、Eureka的认识
Eureka和dubbo框架中经常使用的Zookeeper类似,都是一个用于服务注册和发现的组件。当你创建的微服务需要被其它服务调用时,就需要先在EurekaServer中注册这个服务,方便服务消费者从Eureka查询服务提供者的地址,并通过该地址调⽤服务提供者的接⼝。具体的EurekaServer的架构图如图所示:
二、EurekaServer的创建
1、利用IDEA提供模板,并在其中选择好相应的依赖。
具体配置文件内容如下:
<?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.4.9</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>eurekaServer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eurekaServer</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2020.0.3</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
注意:在选择依赖版本时,应注意SpringCloud和SpringBoot的版本要相对应。
2、在自动生成的启动器上,加上注解@EnableEurekaServer来启动EurekaServer。
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
3、设置配置文件,配置相应的端口和信息。
server:
port: 9004
spring:
application:
name: eureka-server
eureka:
client:
service-url:
# eureka 服务地址,如果是集群的话;需要指定其它集群eureka地址
defaultZone: http://127.0.0.1:9004/eureka
# 不注册⾃⼰
register-with-eureka: false
# 不拉取服务
fetch-registry: false
4、如果要测试是否创建成功,可以在服务器启动之后访问相应的端口和地址就能看见控制页面。
三、服务提供者的创建
1、在利用模板创建服务提供者的方式和上一步大致相同,就是需要选择的依赖部分不一样。
<?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.4.9</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.kkb</groupId>
<artifactId>billServer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>billServer</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2020.0.3</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2、在启动器类上添加注解@EnableDiscoveryClient。
@SpringBootApplication
@EnableDiscoveryClient
public class BillServerApplication {
public static void main(String[] args) {
SpringApplication.run(BillServerApplication.class, args);
}
}
3、在配置文件中设置相应的参数。
server:
port: ${port:9001}
spring:
application:
name: billServer
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:9004/eureka
fetch-registry: true
register-with-eureka: true
4、这时先启动Eureka,再启动服务提供者,访问Eureka的控制页面就可以看见注册的服务列表了。
四、创建服务消费者
1、在模板中选择相应的依赖。具体依赖如下:
<?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.4.9</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>makeBill</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>makeBill</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2020.0.3</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2、在配置文件中配置相应的参数:
server:
port: 9002
spring:
application:
name: makeServer
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:9004/eureka
3、改造启动类,在类名上加上注解@EnableDiscoveryClient,并在类中加上一个返RestTemplate的单例方法。为了在调用服务时实现负载均衡,在该方法上加上注解@LoadBalnced,具体代码如下:
@SpringBootApplication
@EnableDiscoveryClient
public class MakeBillApplication {
public static void main(String[] args) {
SpringApplication.run(MakeBillApplication.class, args);
}
@Bean
@LoadBalanced//实现负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
4、在controller层代码中,需要调用服务时,可以使用RestTemplate来调用服务。如果有调用的服务有多个端口可以实现负载均衡时,在编写url地址就不要指定具体的地址和端口,换成服务名就行。
@Resource
private RestTemplate restTemplate;
@GetMapping("/text/{id}")
public ResponseEntity<LastResult> getResultById(@PathVariable("id") Integer id){
String url = "http://billServer/bill/test/list/"+id;
LastResult payment = restTemplate.getForObject(url, LastResult.class);
return ResponseEntity.ok(payment);
}