一、创建主工程
首先创建一个主Maven工程,在其pom文件引入依赖,spring Boot版本为2.1.9.RELEASE,Spring Cloud版本为Greenwich.RELEASE。这个pom文件作为父pom文件,起到依赖版本控制的作用,其他module工程继承该pom。这一系列文章全部采用这种模式,其他文章的pom跟这个pom一样。再次说明一下,以后不再重复引入。
代码如下:
<?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>com.zn</groupId>
<artifactId>springcloudstudy</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>zn</name>
<description>Demo for study</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
<lombok.version>1.18.6</lombok.version>
<guava.version>23.0</guava.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</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>
</plugin>
</plugins>
</build>
</project>
二、启动注册中心
三部曲
工程名 eureka-server-one
1、引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
2、配置文件
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
spring:
application:
name: eurka-server
3、主类加配置
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerOne {
public static void main(String[] args) {
SpringApplication.run(EurekaServerOne.class,args);
}
}
4、启动
三、创建服务提供者
工程名称 user-provider-one
1、配置依赖
<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>
</dependencies>
2、配置文件
server:
port: 8100
spring:
application:
name: user-provider
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
3、添加注解
@SpringBootApplication
@EnableEurekaClient
public class UserProvider {
public static void main(String[] args) {
SpringApplication.run(UserProvider.class,args);
}
}
4、业务实现
@Data
public class User {
private Integer id;
private String username;
private String password;
private String address;
public User(Integer id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
}
@RestController
public class UserController {
@Value("${server.port}")
private String address;
private static Map<Integer,User> users = ImmutableMap.of(
1,new User(1, "zhangsan", "123456"),
2,new User(2, "lisi", "654321")
);
@GetMapping("/user")
public List<User> getUsers() {
return Lists.newArrayList(users.values());
}
@GetMapping("/user/{id}")
public User getUserById(@PathVariable Integer id){
User user = users.get(id);
user.setAddress(assress);
return user;
}
}
四、创建服务消费者 rest+ribbon
工程名字 consumer-ribbon
使用ribbon做负载均衡
1、引入依赖
<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.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
2、修改配置
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8100
spring:
application:
name: consumer-ribbon
3、添加注解
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class ConsumerRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerRibbonApplication.class, args);
}
//添加一个具有负载均衡能力的restTemplate
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
4、业务实现
public interface UserService {
User getUserById(Integer id);
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private RestTemplate restTemplate;
@Override
public User getUserById(Integer id) {
return restTemplate.getForEntity("http://userprovider/user/"+id,User.class).getBody();
}
}
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("cuser/{id}")
public User getUser(@PathVariable Integer id){
return userService.getUserById(id);
}
}
为了体现负载均衡,再建一个user提供者
五、创建消费者--Feign实现
Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。
简而言之:
- Feign 采用的是基于接口的注解
- Feign 整合了ribbon,具有负载均衡的能力
- 整合了Hystrix,具有熔断的能力
创建工程 consumer-feign
1、引入依赖
<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.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2、修改配置
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8200
spring:
application:
name: service-feign
3、主类加注解
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@EnableFeignClients
public class ServiceFeignApplication {
public static void main(String[] args) {
SpringApplication.run( ServiceFeignApplication.class, args );
}
}
4、业务代码
@FeignClient("user-provider")
public interface UserService {
/**
* 远程调动方法
* @param id
* @return
*/
@GetMapping("/user/{id}")
User getUserById(@PathVariable Integer id);
}
在Web层的controller层,对外暴露一个”/hi”的API接口,通过上面定义的Feign客户端SchedualServiceHi 来消费服务。代码如下:
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/fuser/{id}")
public User getUserById(@PathVariable Integer id){
return userService.getUserById(id);
}
}
六、创建熔断器
1)ribbon
1、添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2、添加注解
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
@EnableHystrix
public class ConsumerRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerRibbonApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
3、改造业务
@Service
public class UserServiceImpl implements UserService {
@Autowired
private RestTemplate restTemplate;
@Override
@HystrixCommand(fallbackMethod = "fallback")
public User getUserById(Integer id) {
return restTemplate.getForEntity("http://user-provider/user/"+id,User.class).getBody();
}
public User fallback(Integer id){
return new User(id,"default","123","0.0.0.0");
}
}
2)feign
Feign是自带断路器的,在D版本的Spring Cloud之后,它没有默认打开。需要在配置文件中配置打开它,在配置文件加以下代码:
1、修改注解
feign:
hystrix:
enabled: true
2、改造业务
@FeignClient(value = "user-provider",fallback = UserFallBack.class)
public interface UserService {
/**
* 远程调动方法
* @param id
* @return
*/
@GetMapping("/user/{id}")
User getUserById(@PathVariable Integer id);
}
需要实现降级方法,实现UserService:
@Component
public class UserFallBack implements UserService {
@Override
public User getUserById(Integer id) {
return new User(id,"defaultFeign","123","feign");
}
}
七、创建spring cloud config统一配置中心
1)服务端
1、添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
2、添加注解
@EnableConfigServer
@SpringBootApplication
public class ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class, args);
}
}
3、添加配置
server:
port: 8500
spring:
application:
name: configer-senter
cloud:
config:
server:
native:
search-locations: classpath:/config
4、在resource目录新建config目录创建统一配置
user:
name: lusy
password: 18
2)客户端
1.添加maven配置文件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
2.设置获取配置中心的配置信息,可以什么也不配,默认本地8888
@Value("${user.password}")
private String password;
@Value("${user.name}")
private String name;
@GetMapping("/config/user/{id}")
public User getUserFromConfigCenter(@PathVariable Integer id){
return new User(id,name,password,"3.3.3.3");
}
3.启动服务并测试
如果在application.yml中对config客户端进行配置,发现不会不生效
增加 bootstrap.yml
1.加载顺序的先后,bootstrap会先加载,在结合configserver一起使用时,bootstrap属性文件更适合做一些引导下文的配置。
2.在结合configserver使用时,bootstrap更多的是配置一些不经常变化甚至不变化的属性。application属性文件可更灵活的配置一些属性.
spring:
profiles:
active: dev
cloud:
config:
uri: http://127.0.0.1:8500
证明配置服务中心可以从远程程序获取配置信息,http请求地址和资源文件映射如下:,可参考
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
八、服务网关
1、引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</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-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
2、添加注解
@SpringBootApplication
@EnableDiscoveryClient
@EnableEurekaClient
@EnableZuulProxy
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class,args);
}
}
3、添加配置
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8500
spring:
application:
name: gateway-zuul
zuul:
routes:
api-a:
path: /api-a/**
serviceId: consumer-ribbon
api-b:
path: /api-b/**
serviceId: consumer-feign
网友评论