一般springcloud配置
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private LoadBalancerClient client;
@GetMapping("{id}")
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"),//访问超过1s则返回失败办法
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000"),//熔断器休眠时间
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"), //熔断器打开阈值
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),//熔断器请求多少次才触发开关
}, fallbackMethod = "fallbackqueryByid")
public UserBean queryByid(@PathVariable(name = "id") Integer id) {
//这个没有负载均衡
List<ServiceInstance> instances = discoveryClient.getInstances("SPRINGCLOUDSERVICE");
System.out.println(instances.get(0).getHost());//127.0.0.1
System.out.println(instances.get(0).getPort());//8081
UserBean userBean = restTemplate.getForObject("http://"+instances.get(0).getHost()+"/user/"+id, UserBean.class);
System.out.println(userBean);
}
利用Ribbon负载均衡 根据服务名称得到一个实例
负载均衡第一种办法
//因为Eurake集成了Ribbon负载均衡,所以只需开启就行了
ServiceInstance serviceInstance = client.choose("SPRINGCLOUDSERVICE");
userBean = restTemplate.getForObject("http://"+serviceInstance.getHost()+":8081/user/"+id, UserBean.class);
return userBean;
@SpringBootApplication
@EnableDiscoveryClient //开启注册中心,将此服务注册到注册中心管理中 @EnableDiscoveryClient //开启加入eureka注册中心
@EnableCircuitBreaker //开启熔断器 hystrix
public class SpringCloudProviderStart {
public static void main(String[] args) {
SpringApplication.run(SpringCloudProviderStart.class);
}
@Bean
@LoadBalanced //这个注解会拦截一切RestTemplate请求,然后在底层做负载均衡 //开启ribbon负载均衡
public RestTemplate getTemplate() {
return new RestTemplate();
}
}
负载均衡第二种办法
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("{id}")
@HystrixCommand(commandProperties = {
//当请求达到10次,失败概率>50% 则开启熔断器
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"),//访问超过1s则返回失败办法
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000"),//熔断器休眠时间
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"), //熔断器打开阈值百分比
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),//熔断器请求多少次才触发开关
}, fallbackMethod = "fallbackqueryByid")//超过访问设置时间 则返回失败办法
public UserBean queryByid(@PathVariable(name = "id") Integer id) {
UserBean bean = restTemplate.getForObject("http://SPRINGCLOUDSERVICE/user/" + id, UserBean.class);
return bean;
}
//参数,返回类型必须一样 办法名字自定义
public UserBean fallbackqueryByid(Integer id) {
UserBean userBean = new UserBean();
userBean.setName("laowang" + "不好意思,服务器拥挤!");
return userBean;
}
}
两种对比
加入Feign后的区别
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
@EnableFeignClients
public class SpringCloudProviderStart {
public static void main(String[] args) {
SpringApplication.run(SpringCloudProviderStart.class);
}
}
Feign根据springmvc办法去自动实现上面的负载均衡
@FeignClient(name = "SPRINGCLOUDSERVICE",fallback = UserService.class)
public interface UserServiceImp {
@GetMapping("user/{id}")
UserBean queryById(@PathVariable(name = "id") Integer id);
}
Feign访问异常处理的回滚办法是这样的,用一个类实现接口,实现该办法回滚
public class UserService implements UserServiceImp {
@Override
public UserBean queryById(Integer id) {
UserBean userBean = new UserBean();
userBean.setName("服务拥挤,请稍后再尝试");
return userBean;
}
}
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private UserService userService;
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"),//访问超过1s则返回失败办法
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000"),//熔断器休眠时间
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"), //熔断器打开阈值
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),//熔断器请求多少次才触发开关
})
public UserBean queryByid(@PathVariable(name = "id") Integer id) {
UserBean userBean = userService.queryById(id);
return userBean;
}
}
两者优雅开发的对比
Feign的注意事项
#在springCloud中使用feign内嵌的断路器hystrix时。feign中的hystrix不起作用。
#因为熔断器hystrix在feign是关闭状态 需要开启
# 这可能是由于springCloud的版本原因造成的。需要在application.properties配置中开启hystrix:
feign:
hystrix:
enabled: true
重试机制非常重要
# 重试机制
# Eureka为了实现更高的服务可用性,牺牲了一定的一致性,极端情况下它宁愿
# 接收故障实例也不愿丢掉健康实例,正如我们上面所说的自我保护机制。
# 但是,此时如果我们调用了这些不正常的服务,调用就会失败,从而导致其它服务不能正常工作!这显然不是我们愿意看到的。
#例如我们剔除一个服务,或者将一个服务的端口8082改8083
#因为服务剔除的延迟,consumer并不会立即得到最新的服务列表,此时再次访问你会得到错误提示:
#虽然8082是打不开的 但是8083是能够打开的
#因此Spring Cloud 整合了Spring Retry 来增强RestTemplate的重试能力,
#当一次服务调用失败后,不会立即抛出一次,而是再次重试另一个服务
#根据如上配置,当访问到某个服务超时后,它会再次尝试访问下一个服务实例,如果不行就再换一个实例,如果不行,则返回失败。切换次数取决于`MaxAutoRetriesNextServer`参数的值
#引入spring-retry依赖
#<groupId>org.springframework.retry</groupId>
#<artifactId>spring-retry</artifactId>
#spring-receiver: #存在错误提示 失败提示很快 下面失败提示很慢
# ribbon:
# ConnectTimeout: 1000 # Ribbon的连接超时时间
# ReadTimeout: 2000 # Ribbon的数据读取超时时间
# OkToRetryOnAllOperations: false # 是否对所有操作都进行重试
# MaxAutoRetriesNextServer: 3 # 切换实例的重试次数
# MaxAutoRetries: 3 # 对当前实例的重试次数
ribbon:
#连接超时时间(ms) 1s时间没有拿到超时时常,则抛出异常
ConnectTimeout: 1000
#业务逻辑超时时间(ms) 2s时间没有读取到数据 则抛出时常 这个是feign需要配置Ribbon的属性
ReadTimeout: 2000
#同一台实例最大重试次数,不包括首次调用
MaxAutoRetries: 3
#重试负载均衡其他的实例最大重试次数,不包括首次调用
MaxAutoRetriesNextServer: 3
#是否所有操作都重试
OkToRetryOnAllOperations: false
Feign访问异常处理的回滚办法是这样的,用一个类实现接口,实现该办法回滚
public class UserService implements UserServiceImp {
@Override
public UserBean queryById(Integer id) {
UserBean userBean = new UserBean();
userBean.setName("服务拥挤,请稍后再尝试");
return userBean;
}
}
消费者的Euraka的配置常用属性
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka/,http://127.0.0.1:10087/eureka/,http://127.0.0.1:10088/eureka/
fetch-registry: true #消费者是否拉起eureka服务列表 默认true
registry-fetch-interval-seconds: 3 #默认30 也就是30s会想注册中心拉取一次eureka服务列表
instance:
prefer-ip-address: true
instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
ip-address: 127.0.0.1
logging:
level:
com.wchulian: debug
Feign的源码实现过程:
1、@EnableFeignClients开启FeignClient的功能
2、实现Feign接口(在接口上面加@FeignClient)
3、程序启动后,扫描所有的@FeignClient类,放到IoC容器中
4、当接口被调用,通过代理生产RequestTemplate模板
5、根据RequestTemplate模板生产HTTP请求的Request对象
6、Client处理Request对象
、最后LoadBalanceClient结合Ribbon进行负载均衡
消费者--Eureka--提供服务者三者配置的区别
#消费者
eureka:
client:
fetch-registry: true #消费者是否拉起eureka服务列表 默认true
registry-fetch-interval-seconds: 3 #默认30 也就是30s会想注册中心拉取一次eureka服务列表
#提供服务者
#每30s他会向注册中心发起请求告诉注册中心我还活着还是挂了 默认30 服务提供者才用,消费者只是拉取fetch
lease-renewal-interval-in-seconds: 30
#90s内如果收不到这个服务的任何请求,将会提出注册中心 默认90 服务提供者才用 , 消费者只是拉取fetch
lease-expiration-duration-in-seconds: 90
mybatis:
#因为mybatis生成javabean对象用到javabean类 这个注解就是告诉mybatis去这里找
#POJO扫描包来让mybatis自动扫描到自定义的POJO
type-aliases-package: com.wchulian.entity
# #90s内如果收不到这个服务的任何请求,将会提出注册中心 默认90 服务提供者才用 , 消费者只是拉取fetch
# lease-expiration-duration-in-seconds: 60 #20s内没续约 则断开服务
# # #每30s他会向注册中心发起请求告诉注册中心我还活着还是挂了 默认30
#服务提供者才用,
#消费者只是拉取fetch
# lease-renewal-interval-in-seconds: 3 #每隔3s续约|心跳一次给注册中心 告诉他还活着
# #这里写了什么调用的时候他就会显示什么,getHost()它得到的就是这个的值
# ip-address: 127.0.0.1
# #默认为false 优先使用Ip作为地址
# prefer-ip-address: true
#Eureka的配置
eureka:
server:
eviction-interval-timer-in-ms: 1000 #失效剔除间隔
enable-self-preservation: false #关闭自我保存
分布式知识点
* https://blog.csdn.net/feiying0canglang/article/details/122937727
* 这个非常重要Eureka挂了,但微服务还能调通。
* 但是有一个前提就是pricider的ip和端口等信息没变 如果变了就不行了
* 为何eureka存在的时候,privider即使变了也不影响,因为privider会
* 将自己最新的IP:端口等信息提供给eureka注册中心
* 从而实现动态分布
常见的注解
/**@EnableEurekaClient为何不推荐这种
* 写了就代表只能支持eurake
* 然后注册中心有 ZooKeeper、Eureka、Consul 、Nacos
*
* 推荐使用@EnableDiscoveryClient
*@EnableDiscoveryClient:开启注册中心服务
*@SpringBootApplication:开启springboot功能入口开关
*@EnableCircuitBreaker :开启线路熔断器 雪崩问题 服务熔断 线程堵塞 访问超时
*@SpringCloudApplication=@EnableDiscoveryClient+@SpringBootApplication+@EnableCircuitBreaker
* * */
@EnableFeignClients // 开启Feign功能
/**
* 不能直接放在main/java 文件下
* 启动类所在的包是最顶部的包
*@SpringBootApplication这个注解的类有下面三个注解
*
* SpringBootConfiguration 这个等同于@Configuration 也就是配置的类 不过一个项目只有一个SpringBootConfiguration 其他都是Configuration
* @EnableAutoConfiguration 这个注解就是spring根据你的业务 或者已经配置的bean去猜测你所需的配置 也就是一个自动配置开关
* @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
* @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
*
* 这个配置相当重要 就是他就是一个组件扫描配置 你可以指定扫描哪个包,如果你不指定
* 他就会根据@SpringBootApplication这个注解也就是入口所在的包开始扫描
* 如果控制器不在这个入口配置器的包下 那么这个控制器将不被扫描到 也就无法使用
* */
@SpringBootApplication
/**
* 跟数据相关的服务 必须配置@MapperScan、
* 来告诉spring mybatis的mapper映射问题在这个包
* 在application.yml 配置了 type-aliases-package: com.wchulian.entity
* 这个javebean和mapper文件路径映射全部搞定 那么利用通用mapper自动生成mysql语句
* 并得到想要的数据*/
@MapperScan("com.wchulian.user.mapper")
private LoadBalancerClient client;//RibbonLoadBalancerClient改成 LoadBalancerClient client;才不报错
唯一错误|不甘
feign:一直触发熔断器 也没看到任何地方有误 抛出异常也没看到任何错误信息
版权说明
文章采用: 《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权。版权声明:未标注转载均为本站原创,转载时请以链接形式注明文章出处。如有侵权、不妥之处,请联系站长删除。敬请谅解!
常见资源合集和破解 fmvvvteih...