在pom.xml中加入spring-boot-starter-parent让当前项目变成一个springboot的子项目,并且父项目管理微服务的所有依赖,但是不引用,由子项目自己去引用自己要使用的依赖。最后还需要导入一些公共的依赖包。
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.2.5.RELEASEversion>
parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>Hoxton.SR3version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
dependency>
dependencies>
创建一个子模块eureka-server,并在pom.xml中加入spring-cloud-starter-netflix-eureka-server
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
dependency>
dependencies>
设置一个启动类
@SpringBootApplication
@EnableEurekaServer // 标识当前服务是一个Eureka的服务端
public class EurekaApp {
public static void main(String[] args) {
SpringApplication.run(EurekaApp.class, args);
}
}
在配置文件中配置eureka的信息
server:
port: 8761 # 标识当前Eureka服务端的端口号
eureka:
instance:
hostname: localhost # 当前Eurek的实例名称
client:
registerWithEureka: false # 在客户端依赖中默认为true,所以服务端需要关闭
fetchRegistry: false # 在客户端依赖中默认为true,所以服务端需要关闭
serviceUrl: # http://localhost:8761/eureka/
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
可以通过地址localhost:8761访问eureka的服务端
server模块底下创建一个order-server模块(同user-server模块类似)
server模块底下创建一个user-server模块
首先在pom.xml中引入eureka-client相关依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-eurekaartifactId>
<version>1.4.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuator artifactId>
dependency>
dependencies>
yml配置文件中配置相关信息,设置端口号为10010,访问eureka的地址为http://localhost:8761/eureka/,并且设置了一个实例名,将服务名设置为user-server
#Eureka配置:服务注册到哪里
server:
port: 10010 # 标识当前Eureka客户端的端口号
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
instance-id: ${spring.application.name}:${server.port} #修改Eureka上的默认描述信息
prefer-ip-address: true
#info配置
info:
# 项目的名称
app.name: springcloud-zcy
# 公司的名称
company.name: com.zcy
spring:
application:
name: user-server
创建一个启动类
@SpringBootApplication
// @EnableEurekaClient 开启Eureka客户端注解,在服务启动后自动向注册中心注册服务
@EnableEurekaClient
public class UserServer {
public static void main(String[] args) {
SpringApplication.run(UserServer.class, args);
}
}
启动项目就可以在eureka服务端页面中看到user-server和order-server的信息了
首先在配置里面多设置一个UserServer,然后通过更改端口号依次启动
在OrderServer启动类中添加负载均衡器
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public RandomRule randomRule() {
return new RandomRule();
}
OrderController通过服务名user-server去发送get请求访问,返回User
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return restTemplate.getForObject("http://user-server/user/" + id, User.class);
}
UserController中也是返回User,为了可以直观地看到端口号port的变化,将其从配置文件中获取打印出来
@RestController
@RequestMapping("/user")
public class UserController {
@Value("${server.port}")
private String port;
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return new User(id, "张三" + port, 16);
}
}
添加OpenFeign所需要的
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
在启动类中添加@EnableFeignClients注解,来启用OpenFeign
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class PayServer {
public static void main(String[] args) {
SpringApplication.run(PayServer.class, args);
}
}
由于我们要在这里使用到Hystrix,所以需要再yml配置文件中添加
feign:
hystrix:
enabled: true #开启熔断支持
接下来就是OpenFeign的实战演示,在此之前先看一下之前Ribbon的RestTemplate负载均衡调用有多麻烦
{{select * from blocks where id=‘20230617172238-ywid01e’}}
需要对访问地址进行拼接,如果地址多的话就会显得非常复杂,所以可以采用OpenFeign来进行简化,由于我们在启动类上面加了@EnableFeignClients注解,当项目启动时就会去扫描带有@FeignClient注解的接口,然后通过JDK动态代理生成一个RestTemplate对象,交给Spring容器管理
@FeignClient(value = "user-server", path = "/user", contextId = "userServer", fallbackFactory = FallbackUserService.class)
public interface UserService {
@GetMapping("/{id}")
User getUser(@PathVariable("id") Long id);
}
由于我们要集成使用Hystrix,所以在@FeignClient注解中添加了fallbackFactory,并指定了FallbackUserService类来实现熔断降级,注意类中一定要添加@Component将此类交给Spring容器管理
@Component
public class FallbackUserService implements FallbackFactory {
@Override
public UserService create(Throwable throwable) {
return id -> new User(-1L, "被熔断了!", 16);
}
}
然后我们就可以在Controller接口中去调用这个负载均衡接口UserService,去向user-server模块发请求
@RestController
@Slf4j
@RequestMapping("/pay")
public class PayController {
@Resource
private UserService userService;
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
User user = userService.getUser(id);
return user;
}
}
首先依旧是先导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-zuulartifactId>
dependency>
dependencies>
配置application.yml,分别是设置端口号,将此模块设置为Eureka的客户端,设置服务名和配置zuul的信息,其中配置zuul信息的时候,配置ignored-services是表明拦截哪些接口,*代表了全部。routes下面就是要放行的服务名,并为每个服务名配置对应的接口路径。
#Eureka配置:服务注册到哪里
server:
port: 10050 # 标识当前Eureka客户端的端口号
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
instance-id: ${spring.application.name}:${server.port} #修改Eureka上的默认描述信息
prefer-ip-address: true
spring:
application:
name: zuul-server
zuul:
ignored-services: "*"
routes:
pay-server: "/pay/**"
user-server: "/user/**"
order-server: "/order/**"
prefix: "/apis"
配置启动类,简单来说就是在启动类上面加上@EnableEurekaClient和@EnableZuulProxy两个注解,分别用来启用Eureka和Zuul组件。
@SpringBootApplication
// 表名此服务是Eure客户端,开启Eureka客户端功能,不加此注解默认也开启客户端功能
@EnableEurekaClient
// 开启Zull服务支持
@EnableZuulProxy
public class ZuulServer {
public static void main(String[] args) {
SpringApplication.run(ZuulServer.class, args);
}
}