统计
  • 建站日期:2021-03-10
  • 文章总数:518 篇
  • 评论总数:151 条
  • 分类总数:32 个
  • 最后更新:4月20日
文章 未分类

SpringCloud二次基础复习

梦幻书涯
首页 未分类 正文

一般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;
    }
}

两种对比


SpringCloud二次基础复习
-梦幻书涯 - 莫問前路遙遠- 與君風雪
-第1
张图片

加入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;
    }
}

两者优雅开发的对比


SpringCloud二次基础复习
-梦幻书涯 - 莫問前路遙遠- 與君風雪
-第2
张图片

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)》许可协议授权。
版权声明:未标注转载均为本站原创,转载时请以链接形式注明文章出处。如有侵权、不妥之处,请联系站长删除。敬请谅解!

这篇文章最后更新于2022-5-21,已超过 1 年没有更新,如果文章内容或图片资源失效,请留言反馈,我们会及时处理,谢谢!
进程,单线程,多线程的区别和联系
« 上一篇
SpringCloudTwo
下一篇 »

发表评论

HI ! 请登录
注册会员,享受下载全站资源特权。
Array

日历

热门文章