SpringCloud学习第二天
Eureka相关配置
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10087/eureka # 设置eureka服务注册的地址
register-with-eureka: false # 不注册自己,自己不会显示在服务列表中
registry-fetch-interval-seconds: 30 # 获取服务列表
instance:
prefer-ip-address: true # 写死ip地址为本机127.0.0.1
ip-address: 127.0.0.1
lease-renewal-interval-in-seconds: 30 # 心跳时长,30s发送一次
lease-expiration-duration-in-seconds: 90 # 过期时长,90s没有响应表示挂了,标记需要剔除
server:
enable-self-preservation: false # 关闭自我保护模式(缺省为打开),自我保护:判断是否有网络问题,停止失效剔除
eviction-interval-timer-in-ms: 60000 # 扫描失效服务的间隔时长,到时间后一次性剔除(缺省为60*1000ms)
Ribbon负载均衡
启动两台user-service tomcat服务,端口分别为8081,8082
![image-20230627102259943](/Users/zyh/Library/Application Support/typora-user-images/image-20230627102259943.png)
在consumer的pom文件中引入ribbon
<!-- 负载均衡 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
实现user-service负载均衡
方法一:修改ConsumerController
@RestController
@RequestMapping("consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient client; // Ribbon
@GetMapping("{id}")
public String queryById(@PathVariable("id") Long id) {
ServiceInstance instance = client.choose("user-service"); // 拿到一个经过负载均衡计算后的服务
// 拼接url
String url = "http://"+instance.getHost()+":"+instance.getPort()+"/user/" + id;
String user = restTemplate.getForObject(url, String.class);
return user
}
}
启动访问,可以随机获取8081和8082的服务
方法二:
在启动类中的RestTemplate上添加@LoadBalanced
@EnableDiscoveryClient
@SpringBootApplication
public class ConsumerApplication {
@LoadBalanced // 实现负载均衡
@Bean
public RestTemplate restTemplate(){
return new RestTemplate(); // restTemplate获取到可以调用其他服务器接口的实例对象
}
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class);
}
}
修改ConsumerController
@RestController
@RequestMapping("consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("{id}")
public String queryById(@PathVariable("id") Long id) {
// 使用注解方式实现负载均衡
String url = "http://user-service/user/"+id;
String user = restTemplate.getForObject(url, String.class);
return user
}
}
原理:底层通过LoadBalancerInterceptor拦截器,根据服务名动态获取服务ip地址,实现默认的轮徇调用可用服务
Ribbon配置
consumer application.yml
user-service: # 要调用的服务名称
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 配置负载均衡方式为:随机
Hystrix保护机制
在分布式应用中有着许多的服务,某个服务可能存在调用失败的情况,在服务之间调用时会出现阻塞的情况,当访问过大时,问题会更加严重,导致许多请求无法响应,从而耗尽服务器资源,整个集群宕机,称为雪崩效应。
线程隔离和服务降级
服务调用方consumer使用Hystrix
<!-- hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
启动类
@EnableCircuitBreaker // Hystrix熔断器
@EnableDiscoveryClient
@SpringBootApplication
// @SpringCloudApplication 等同于上面三个注解
public class ConsumerApplication {
@LoadBalanced // 实现负载均衡
@Bean
public RestTemplate restTemplate(){
return new RestTemplate(); // restTemplate获取到可以调用其他服务器接口的实例对象
}
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class);
}
}
修改user-service项目 UserService
@Service
public class UserService {
@Autowired
private UserDao userDao;
public User queryById(Long id) {
// 模拟服务器超时,休眠2s
try {
Thread.sleep(2000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
User user = userDao.selectByPrimaryKey(id);
return user;
}
}
修改ConsumerController
1、在单个方法上使用Hystrix
@RestController
@RequestMapping("consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("{id}")
@HystrixCommand(fallbackMethod = "queryByIdFallback") // 开启服务的线程隔离和服务降级处理(熔断处理)
public String queryById(@PathVariable("id") Long id) {
// 使用注解方式实现负载均衡
String url = "http://user-service/user/"+id;
String user = restTemplate.getForObject(url, String.class);
return user
}
// 服务降级方法,两个方法的返回值和参数必须一致
public String queryByIdFallback(Long id) {
return "服务器拥挤,请稍后再试";
}
}
2、在类上统一使用
@DefaultProperties(defaultFallback = "defaultFallback") // 统一的降级逻辑处理
@RestController
@RequestMapping("consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("{id}")
@HystrixCommand // 统一处理,此处不需要fallbackMethod,只需要加@HystrixCommand注解
public String queryById(@PathVariable("id") Long id) {
// 使用注解方式实现负载均衡
String url = "http://user-service/user/"+id;
String user = restTemplate.getForObject(url, String.class);
return user
}
// 统一服务降级逻辑方法,不能再写参数,返回值不用一样
public String defaultFallback() {
return "服务器拥挤,请稍后再试";
}
}
以上两个方法都可以实现服务降级,在接口异常时返回服务器异常错误提示。
熔断器相关配置
@HystrixCommand(commandProperties = {
// 定义单个方法请求的超时时长,全局需要在配置文件中配置
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value="3000")
})
@HystrixCommand(commandProperties = {
// 触发熔断最小请求次数
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value="10"),
// 熔断器恢复close状态的时间(休眠时长),缺省为5s
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value="10000"),
// 触发熔断的失败请求错误占比,超过百分之60出发熔断器开启
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value="60")
})
yml全局配置
hystrix:
command:
default: #全局配置服务降级处理时长
execution:
isolation:
thread:
timeoutInMilliseconds: 3000 # 默认是1s
user-service: #配置某个服务或方法(写方法名)的服务降级处理时长
execution:
isolation:
thread:
timeoutInMilliseconds: 3000
Feign
consumer调用方-引入依赖
<!-- feign依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
启动类添加注解
@EnableCircuitBreaker // Hystrix熔断器
@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients // 启用feign注解
// @SpringCloudApplication 等同于上面三个注解
public class ConsumerApplication {
/* RestTemplate不再需要
@LoadBalanced // 实现负载均衡
@Bean
public RestTemplate restTemplate(){
return new RestTemplate(); // restTemplate获取到可以调用其他服务器接口的实例对象
}
*/
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class);
}
}
新增client/UserClient接口
@FeignClient("user-service") // 请求的服务名称
public interface UserClient {
@GetMapping("user/{id}")
User queryById(@PathVariable("id") Long id);
}
ConsumerController
@DefaultProperties(defaultFallback = "defaultFallback") // 统一的降级逻辑处理
@RestController
@RequestMapping("consumer")
public class ConsumerController {
...
@Autowired
private UserClient userClient; // feign
public User queryById(@PathVariable("id") Long id) {
return userClient.queryById(id);
}
}
Feign实现Hystrix
feign框架实现了ribbon负载均衡;Hystrix熔断,默认关闭,需要手动配置开启feign.hystrix.enabled: true
consumer application.yml
feign:
hystrix:
enabled: true # 开启feign的熔断功能
UserClient
@FeignClient(value = "user-service", fallback = UserClientFallback.class) // 配置熔断报错实现类 UserClientFallback
public interface UserClient {
@GetMapping("user/{id}")
User queryById(@PathVariable("id") Long id);
}
UserClientFallback
@Component
public class UserClientFallback implements UserClient {
@Override
public User queryById(Long id) {
User user = new User();
user.setName("异常");
return user;
}
}
另外yml全局的hystrix配置也会生效。
标签:String,SpringCloud,class,restTemplate,id,学习,user,public From: https://www.cnblogs.com/meer/p/17510178.html