【SpringCloud】整合Consul+OpenFeign实现微服务+负载均衡(上)
一、服务架构
service-common 核心公共功能服务
service-provider 服务提供者微服务
service-consumer 服务消费者微服务
主要特性:
springcloud+consul+openfeign+ribbion
基于feign_client + rest_template 两种微服务调用方式
二、父pom.xml文件
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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>springcloud-consul</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>service-common</module>
<module>service-provider</module>
<module>service-consumer</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!-- SpringBoot监控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
三、公共服务service-common代码
pom.xml文件
springcloud-consul/service-common/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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springcloud-consul</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service-common</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>
springcloud-consul/service-common/src/main/java/com/example/common/model/UserModel.java
package com.example.common.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserModel implements Serializable {
private String username;
private int age;
private String address;
private String job;
}
springcloud-consul/service-common/src/main/java/com/example/common/service/UserService.java
package com.example.common.service;
import com.example.common.model.UserModel;
import java.util.List;
public interface UserService {
List<UserModel> findAll();
UserModel findById(int id);
String port();
}
四、服务提供者service-provider代码
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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springcloud-consul</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service-provider</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>service-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<includeSystemScope>true</includeSystemScope>
<mainClass>com.example.provider.ConsulProviderApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
springcloud-consul/service-provider/src/main/resources/application.yml
spring:
application:
name: service-provider
profiles:
active: dev
cloud:
consul:
# 服务发现配置
discovery:
# 启用服务发现
enabled: true
# 启用服务注册
register: true
# 服务停止时取消注册
deregister: true
# 表示注册时使用IP而不是hostname
prefer-ip-address: true
# 执行监控检查的频率
health-check-interval: 30s
# 设置健康检查失败多长时间后,取消注册
health-check-critical-timeout: 30s
# 健康检查的路径
health-check-path: /actuator/info
# 服务注册标识,格式为:应用名称+服务器IP+端口
instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
server:
port: 8011
springcloud-consul/service-provider/src/main/resources/bootstrap.yml
# bootstrap.yml
# consul 使用动态配置,必须在bootstrap.yml中配置好动态配置项目的配置
spring:
cloud:
consul:
host: localhost
port: 8500
#enabled将此值设置为“false”禁用Consul配置
config:
enabled: true #默认是true --
format: YAML # 表示consul上面文件的格式 有四种 YAML PROPERTIES KEY-VALUE FILES
data-key: data #表示consul上面的KEY值(或者说文件的名字) 默认是data
# watch选项为配置监视功能,主要监视配置的改变
watch:
enabled: true
delay: 10000
wait-time: 30
springcloud-consul/service-provider/src/main/java/com/example/provider/service/impl/UserServiceImpl.java
package com.example.provider.service.impl;
import com.example.common.model.UserModel;
import com.example.common.service.UserService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Value("${server.port}")
int port;
@Override
public List<UserModel> findAll() {
return Arrays.asList(
new UserModel("张三", 22, "西安", "Java开发"),
new UserModel("李四", 24, "深圳", "总经理助理"),
new UserModel("王五", 56, "上海", "HR"),
new UserModel("赵六", 12, "广州", "PHP开发"),
new UserModel("宋七", 42, "重庆", "运营")
);
}
@Override
public UserModel findById(int id) {
return new UserModel("lucy", 44, "西雅图", "董事长");
}
@Override
public String port() {
return "Port: " + port;
}
}
springcloud-consul/service-provider/src/main/java/com/example/provider/web/HiController.java
package com.example.provider.web;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HiController {
@Value("${server.port}")
String port;
@GetMapping("/hi")
public String home(@RequestParam String name) {
return "hi "+name+",i am from port:" +port;
}
@GetMapping("/port")
public String port() {
return port;
}
}
springcloud-consul/service-provider/src/main/java/com/example/provider/web/UserController.java
package com.example.provider.web;
import com.example.common.model.UserModel;
import com.example.common.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("api/user")
public class UserController {
@Autowired
UserService userService;
@GetMapping("list")
public List<UserModel> findAll() {
return userService.findAll();
}
@GetMapping("get")
public UserModel findById(int id) {
return userService.findById(id);
}
@GetMapping("port")
public String port() {
return userService.port();
}
}
springcloud-consul/service-provider/src/main/java/com/example/provider/ConsulProviderApplication.java
package com.example.provider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(basePackages = {"com.example"})
@EnableDiscoveryClient
public class ConsulProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ConsulProviderApplication.class, args);
System.out.println(".....................................");
System.out.println("....Provider Application started.....");
System.out.println(".....................................");
}
}
五、服务消费者service-consumer代码
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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springcloud-consul</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service-consumer</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>service-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<includeSystemScope>true</includeSystemScope>
<mainClass>com.example.consumer.ConsulConsumerApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
springcloud-consul/service-consumer/src/main/java/com/example/consumer/feign/HiFeign.java
package com.example.consumer.feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(value = "service-provider", contextId = "hi")
public interface HiFeign {
@GetMapping(value = "/hi")
String sayHiFromFeign(@RequestParam(value = "name") String name);
}
springcloud-consul/service-consumer/src/main/java/com/example/consumer/feign/UserFeign.java
package com.example.consumer.feign;
import com.example.common.model.UserModel;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@FeignClient(value = "service-provider", contextId = "user")
@RequestMapping("api/user")
public interface UserFeign {
@GetMapping(value = "list")
List<UserModel> findAll();
@GetMapping(value = "get")
UserModel findById(@RequestParam(value = "id") int id);
@GetMapping(value = "port")
String getPort();
}
springcloud-consul/service-consumer/src/main/java/com/example/consumer/service/HiService.java
package com.example.consumer.service;
import com.example.consumer.feign.HiFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class HiService {
@Autowired
HiFeign hiFeign;
public String sayHi(String name) {
return hiFeign.sayHiFromFeign(name);
}
}
springcloud-consul/service-consumer/src/main/java/com/example/consumer/service/impl/UserFeignServiceImpl.java
package com.example.consumer.service.impl;
import com.example.common.model.UserModel;
import com.example.common.service.UserService;
import com.example.consumer.feign.UserFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserFeignServiceImpl implements UserService {
@Autowired
UserFeign userFeign;
@Override
public List<UserModel> findAll() {
return userFeign.findAll();
}
@Override
public UserModel findById(int id) {
return userFeign.findById(id);
}
@Override
public String port() {
return userFeign.getPort();
}
}
springcloud-consul/service-consumer/src/main/java/com/example/consumer/service/impl/UserRestServiceImpl.java
package com.example.consumer.service.impl;
import com.example.common.model.UserModel;
import com.example.common.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@Service
public class UserRestServiceImpl implements UserService {
@Autowired
RestTemplate restTemplate;
@Override
public List<UserModel> findAll() {
ResponseEntity<List<UserModel>> responseEntity = restTemplate.exchange(
"http://service-provider/api/user/list",
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<UserModel>>() {
});
return responseEntity.getBody();
}
@Override
public UserModel findById(int id) {
ResponseEntity<UserModel> responseEntity = restTemplate.exchange(
"http://service-provider/api/user/get?id=" + id,
HttpMethod.GET,
null,
new ParameterizedTypeReference<UserModel>() {
});
return responseEntity.getBody();
}
@Override
public String port() {
ResponseEntity<String> responseEntity = restTemplate.exchange(
"http://service-provider/api/user/port",
HttpMethod.GET,
null,
new ParameterizedTypeReference<String>() {
});
return responseEntity.getBody();
}
}
springcloud-consul/service-consumer/src/main/java/com/example/consumer/web/HiController.java
package com.example.consumer.web;
import com.example.consumer.service.HiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HiController {
@Autowired
HiService hiService;
@Value("${server.port}")
String port;
@GetMapping("/hi")
public String home(@RequestParam String name) {
return hiService.sayHi(name);
}
@GetMapping("/port")
public String port() {
return port;
}
}
springcloud-consul/service-consumer/src/main/java/com/example/consumer/web/UserFeignController.java
package com.example.consumer.web;
import com.example.common.model.UserModel;
import com.example.common.service.UserService;
import com.example.consumer.service.impl.UserFeignServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("feign-api/user")
public class UserFeignController implements UserService {
@Autowired
UserFeignServiceImpl userService;
@Override
@GetMapping("/list")
public List<UserModel> findAll() {
return userService.findAll();
}
@Override
@GetMapping("/get")
public UserModel findById(int id) {
return userService.findById(id);
}
@Override
@GetMapping("port")
public String port() {
return userService.port();
}
}
springcloud-consul/service-consumer/src/main/java/com/example/consumer/web/UserRestController.java
package com.example.consumer.web;
import com.example.common.model.UserModel;
import com.example.common.service.UserService;
import com.example.consumer.service.impl.UserRestServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("rest-api/user")
public class UserRestController implements UserService {
@Autowired
UserRestServiceImpl userRestService;
@GetMapping("list")
public List<UserModel> findAll() {
return userRestService.findAll();
}
@GetMapping("get")
public UserModel findById(int id) {
return userRestService.findById(id);
}
@GetMapping("port")
public String port() {
return userRestService.port();
}
}
springcloud-consul/service-consumer/src/main/java/com/example/consumer/ConsulConsumerApplication.java
package com.example.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@ComponentScan(basePackages = {"com.example"})
@EnableDiscoveryClient
@EnableFeignClients
public class ConsulConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsulConsumerApplication.class, args);
System.out.println(".....................................");
System.out.println("....Consumer Application started.....");
System.out.println(".....................................");
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
springcloud-consul/service-consumer/src/main/resources/application.yml
spring:
application:
name: service-consumer
profiles:
active: dev
cloud:
consul:
# 服务发现配置
discovery:
# 启用服务发现
enabled: true
# 启用服务注册
register: true
# 服务停止时取消注册
deregister: true
# 表示注册时使用IP而不是hostname
prefer-ip-address: true
# 执行监控检查的频率
health-check-interval: 30s
# 设置健康检查失败多长时间后,取消注册
health-check-critical-timeout: 30s
# 健康检查的路径
health-check-path: /actuator/info
# 服务注册标识,格式为:应用名称+服务器IP+端口
instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
server:
port: 8001
springcloud-consul/service-consumer/src/main/resources/bootstrap.yml
# bootstrap.yml
# consul 使用动态配置,必须在bootstrap.yml中配置好动态配置项目的配置
spring:
cloud:
consul:
host: localhost
port: 8500
#enabled将此值设置为“false”禁用Consul配置
config:
enabled: true #默认是true --
format: YAML # 表示consul上面文件的格式 有四种 YAML PROPERTIES KEY-VALUE FILES
data-key: data #表示consul上面的KEY值(或者说文件的名字) 默认是data
# watch选项为配置监视功能,主要监视配置的改变
watch:
enabled: true
delay: 10000
wait-time: 30
六、测试
由于篇幅有限,测试效果见下一篇文章。
https://blog.csdn.net/forest_long/article/details/129288367
还没有评论,来说两句吧...