SpringCloud微服务框架一套就够(下集)

Posted 摸鱼打酱油

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud微服务框架一套就够(下集)相关的知识,希望对你有一定的参考价值。

个人简介

作者是一个来自河源的大三在校生,以下笔记都是作者自学之路的一些浅薄经验,如有错误请指正,将来会不断的完善笔记,帮助更多的Java爱好者入门。

文章目录

Spring Cloud Netflix

断路器springcloud Hystrix

服务降级

在springcloud-02-comsumer-openFeign-dept80的Pom.xml

<!--        Hystrix-->
          <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

修改它的deptController

@RestController
public class deptController 

    @Autowired
    private deptService deptService;


    @HystrixCommand(fallbackMethod = "queryAllDept_Hystrix",commandProperties = 
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500") //添加超时服务降级
    )
    @RequestMapping("/feign/queryAllDept")
    public List<dept> queryAllDept(String id)
        int i = Integer.parseInt(id);
        if(i<0)
            throw new RuntimeException(); //此处为了触发服务降级fallback
        
        return deptService.queryAllDept();
    


    //服务降级方法,这个方法直接从上面的正常方法复制过来,把名字修改一下即可,参数类型也和正常的方法要一致
    public List<dept> queryAllDept_Hystrix(String id)

        List<dept> depts = deptService.queryAllDept();
        depts.add(new dept("1000","Hystrix_fallback"));
        return depts;
    



主启动类

@SpringBootApplication
@EnableFeignClients
@EnableHystrix //开启Hystrix功能
public class springApplicationFeign80 

    public static void main(String[] args) 

        SpringApplication.run(springApplicationFeign80.class,args);

    

commandProperties支持什么参数属性

我们全局搜索HystrixCommandProperties,往下翻可以看到如下

protected HystrixCommandProperties(HystrixCommandKey key, HystrixCommandProperties.Setter builder, String propertyPrefix) 
        this.key = key;
        this.circuitBreakerEnabled = getProperty(propertyPrefix, key, "circuitBreaker.enabled", builder.getCircuitBreakerEnabled(), default_circuitBreakerEnabled);
        this.circuitBreakerRequestVolumeThreshold = getProperty(propertyPrefix, key, "circuitBreaker.requestVolumeThreshold", builder.getCircuitBreakerRequestVolumeThreshold(), default_circuitBreakerRequestVolumeThreshold);
        this.circuitBreakerSleepWindowInMilliseconds = getProperty(propertyPrefix, key, "circuitBreaker.sleepWindowInMilliseconds", builder.getCircuitBreakerSleepWindowInMilliseconds(), default_circuitBreakerSleepWindowInMilliseconds);
        this.circuitBreakerErrorThresholdPercentage = getProperty(propertyPrefix, key, "circuitBreaker.errorThresholdPercentage", builder.getCircuitBreakerErrorThresholdPercentage(), default_circuitBreakerErrorThresholdPercentage);
        this.circuitBreakerForceOpen = getProperty(propertyPrefix, key, "circuitBreaker.forceOpen", builder.getCircuitBreakerForceOpen(), default_circuitBreakerForceOpen);
        this.circuitBreakerForceClosed = getProperty(propertyPrefix, key, "circuitBreaker.forceClosed", builder.getCircuitBreakerForceClosed(), default_circuitBreakerForceClosed);
        this.executionIsolationStrategy = getProperty(propertyPrefix, key, "execution.isolation.strategy", builder.getExecutionIsolationStrategy(), default_executionIsolationStrategy);
        this.executionTimeoutInMilliseconds = getProperty(propertyPrefix, key, "execution.isolation.thread.timeoutInMilliseconds", builder.getExecutionIsolationThreadTimeoutInMilliseconds(), default_executionTimeoutInMilliseconds);
        this.executionTimeoutEnabled = getProperty(propertyPrefix, key, "execution.timeout.enabled", builder.getExecutionTimeoutEnabled(), default_executionTimeoutEnabled);
        this.executionIsolationThreadInterruptOnTimeout = getProperty(propertyPrefix, key, "execution.isolation.thread.interruptOnTimeout", builder.getExecutionIsolationThreadInterruptOnTimeout(), default_executionIsolationThreadInterruptOnTimeout);
        this.executionIsolationThreadInterruptOnFutureCancel = getProperty(propertyPrefix, key, "execution.isolation.thread.interruptOnFutureCancel", builder.getExecutionIsolationThreadInterruptOnFutureCancel(), default_executionIsolationThreadInterruptOnFutureCancel);
        this.executionIsolationSemaphoreMaxConcurrentRequests = getProperty(propertyPrefix, key, "execution.isolation.semaphore.maxConcurrentRequests", builder.getExecutionIsolationSemaphoreMaxConcurrentRequests(), default_executionIsolationSemaphoreMaxConcurrentRequests);
        this.fallbackIsolationSemaphoreMaxConcurrentRequests = getProperty(propertyPrefix, key, "fallback.isolation.semaphore.maxConcurrentRequests", builder.getFallbackIsolationSemaphoreMaxConcurrentRequests(), default_fallbackIsolationSemaphoreMaxConcurrentRequests);
        this.fallbackEnabled = getProperty(propertyPrefix, key, "fallback.enabled", builder.getFallbackEnabled(), default_fallbackEnabled);
        this.metricsRollingStatisticalWindowInMilliseconds = getProperty(propertyPrefix, key, "metrics.rollingStats.timeInMilliseconds", builder.getMetricsRollingStatisticalWindowInMilliseconds(), default_metricsRollingStatisticalWindow);
        this.metricsRollingStatisticalWindowBuckets = getProperty(propertyPrefix, key, "metrics.rollingStats.numBuckets", builder.getMetricsRollingStatisticalWindowBuckets(), default_metricsRollingStatisticalWindowBuckets);
        this.metricsRollingPercentileEnabled = getProperty(propertyPrefix, key, "metrics.rollingPercentile.enabled", builder.getMetricsRollingPercentileEnabled(), default_metricsRollingPercentileEnabled);
        this.metricsRollingPercentileWindowInMilliseconds = getProperty(propertyPrefix, key, "metrics.rollingPercentile.timeInMilliseconds", builder.getMetricsRollingPercentileWindowInMilliseconds(), default_metricsRollingPercentileWindow);
        this.metricsRollingPercentileWindowBuckets = getProperty(propertyPrefix, key, "metrics.rollingPercentile.numBuckets", builder.getMetricsRollingPercentileWindowBuckets(), default_metricsRollingPercentileWindowBuckets);
        this.metricsRollingPercentileBucketSize = getProperty(propertyPrefix, key, "metrics.rollingPercentile.bucketSize", builder.getMetricsRollingPercentileBucketSize(), default_metricsRollingPercentileBucketSize);
        this.metricsHealthSnapshotIntervalInMilliseconds = getProperty(propertyPrefix, key, "metrics.healthSnapshot.intervalInMilliseconds", builder.getMetricsHealthSnapshotIntervalInMilliseconds(), default_metricsHealthSnapshotIntervalInMilliseconds);
        this.requestCacheEnabled = getProperty(propertyPrefix, key, "requestCache.enabled", builder.getRequestCacheEnabled(), default_requestCacheEnabled);
        this.requestLogEnabled = getProperty(propertyPrefix, key, "requestLog.enabled", builder.getRequestLogEnabled(), default_requestLogEnabled);
        this.executionIsolationThreadPoolKeyOverride = HystrixPropertiesChainedProperty.forString().add(propertyPrefix + ".command." + key.name() + ".threadPoolKeyOverride", (Object)null).build();
    

例如:超时降级execution.isolation.thread.timeoutInMilliseconds和服务熔断的circuitBreaker.enabled和circuitBreaker.requestVolumeThreshold等等都在上面可以找到

全局服务降级

实现全局服务降级主要就是靠@DefaultProperties和@HystrixCommand

进入@DefaultProperties

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface DefaultProperties 
    String groupKey() default "";

    String threadPoolKey() default "";

    HystrixProperty[] commandProperties() default ;

    HystrixProperty[] threadPoolProperties() default ;

    Class<? extends Throwable>[] ignoreExceptions() default ;

    HystrixException[] raiseHystrixExceptions() default ;

    String defaultFallback() default "";


使用方法:这个注解加到消费者的controller层上,必要配置(defaultFallback)也就是默认服务降级方法名称,然后在需要使用默认服务降级的方法上加上@HystrixCommand(不加任何参数)即可

**小坑:注意=======>默认服务降级的方法也就是defaultFallback方法“”不能有任何参数“”,不然就会报错**

比如如下配置

@RestController
@DefaultProperties(defaultFallback = "queryAllDept_Hystrix") //默认全局服务降级,也就是配置上去后,需要服务降级的方法加上@HystrixCommand不加参数即可
public class deptController 

    @Autowired
    private deptService deptService;


//    @HystrixCommand(fallbackMethod = "queryAllDept_Hystrix",commandProperties = 
//            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")
//    )

    @HystrixCommand //触发全局服务降级
    @RequestMapping("/feign/queryAllDept")
    public List<dept> queryAllDept(String id)
        int i = Integer.parseInt(id);
        if(i<0)
            throw new RuntimeException();
        
        return deptService.queryAllDept(id);
    


//    //服务降级方法,全局服务降级方法不能有参数
    public List<dept> queryAllDept_Hystrix()

        List<dept> depts = new ArrayList<>();
        depts.add(new dept("1000","Hystrix_fallback"));
        return depts;
    



服务熔断

Pom.xml

 <!--        Hystrix-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

在springcloud-02-provider-dept8001和8002的controller

@RestController
public class deptController 

    private deptService deptService;

    @Value("$server.port")
    private String port;


    @Autowired
    @Qualifier("deptServiceImpl")
    public void setDeptService(com.boot.service.deptService deptService) 
        this.deptService = deptService;
    
    @GetMapping(path = "/queryAllDept")
    @HystrixCommand(fallbackMethod = "queryAllDept_Hystrix",commandProperties = 
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "20000"),//注意这是毫秒。1秒=1000毫秒
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "50")

    )
    public List<dept> queryAllDept(String id)
        List<dept> depts = deptService.queryAllDept();
        depts.add(new dept("999",port));
//        try 
//            Thread.sleep(1500);
//         catch (InterruptedException e) 
//            e.printStackTrace();
//        

        if(Integer.parseInt(id)<0)
            throw new RuntimeException();
        

        return depts;
    

    /**
     * 服务熔断
     */
    public List<dept> queryAllDept_Hystrix(String id)

        List<dept> depts = deptService.queryAllDept();
        depts.add(new dept("1066","Break"));
        return depts;
    



提供者主启动类:

@SpringBootApplication
@EnableEurekaClient //eureka客户端
@EnableCircuitBreaker //开启服务熔断功能
public class SpringBootApplication8001 

    public static void main(String[] args) 
        SpringApplication.run(SpringBootApplication8001.class,args);


    


Hystrix-Dashboard

创建子模块springcloud-02-hystrix-Dashboard8110

仪表盘的访问页面:

假如端口号是8110:http://localhost:8110/hystrix

Pom.xml

 <dependencies>

        <!--      web和actuator是必备的,******除了gateway网关不能加入web包  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--        actuator用来监控-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

<!--     Hystrix-dashboard-->
         <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>
 
    </dependencies>

配置文件没有要求,就修改端口号即可

server:
  port: 8110
spring:
  application:
    name: hystrixDashboard8110

主启动类:

@SpringBootApplication
@EnableHystrixDashboard //开启了Hystrix仪表盘功能
public class springBootApplication8110 

    public static void main(String[] args) 
        SpringApplication.run(springBootApplication8110.class,args);
    




Bug:Hystrix仪表盘连接不上

解决方法:在每一个需要监控的模块(比如微服务提供者8001和8002)加上如下配置

1.微服务提供者的Pom.xml

<!--     Hystrix-dashboard(微服务提供者)-->
         <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>

2.在微服务提供者8001和8002加上一个bean

@SpringBootApplication
@EnableEurekaClient //eureka客户端
@EnableCircuitBreaker //开启服务熔断功能
public class SpringBootApplication8001 

    public static void main(String[] args) 
        SpringApplication.run(SpringBootApplication8001.class,args);


    
    //解决Hystrix-dashboard连接不上
    @Bean
    public ServletRegistrationBean getServlet() 
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    

Bug:Hystrix仪表盘一直是loading

解决方法:用openFeign去调用一下即可

成功页面👇

服务网关springcloud gateway

小坑:1.注意===》gateWay不能有springBoot-Web的启动器,不然会报错。。。。。。。。

小坑(负载均衡):2.注意==》需要把gateway当作提供者注册到注册中心eureka中,不然不能进行服务网关的负载均衡

服务网关gateway作用:把所有请求都先进入网关gateway,再由gateway进行分发请求,这样的好处就是隐藏分发到的微服务的端口号,安全性更高

配置gateway服务网关

1.创建子模块springcloud-02-gateWay9527

2.打开pom.xml,添加依赖

 		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

3.application.yml

server:
  port: SSM详细的过程,一套就够了

微服务框架之Spring Cloud简介

搭建SpringCloud微服务框架:结构和各个组件

搭建SpringCloud微服务框架:结构和各个组件

SpringCloud 微服务

Java学习微服务架构SpringCloud