# bs-service-a **Repository Path**: SpringCloudTestGroup/bs-service-a ## Basic Information - **Project Name**: bs-service-a - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2018-11-26 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # bs-service-a #### 项目介绍 主要演示 feign 及 Hystrix 的机制的测试 通过 bs-service-a 通过 feign 访问 bs-service-b业务 #### 软件架构 软件架构说明 #### 安装教程 1. pom.xml ``` org.springframework.cloud spring-cloud-starter-openfeign org.springframework.cloud spring-cloud-starter-netflix-hystrix ``` 2. 程序入口 ``` package com.example.a; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Configuration; @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients `标记启用Feign功能` @EnableCircuitBreaker `标记启用hystrix功能` public class ServiceAApplication { public static void main(String[] args) { long starTime = System.currentTimeMillis(); SpringApplication.run(ServiceAApplication.class, args); long endTime = System.currentTimeMillis(); long time = endTime - starTime; System.out.println("\nStart Time: " + (time / 1000) + " s"); System.out.println("..............................................................."); System.out.println("..................Service starts successfully.................."); System.out.println("..............................................................."); } } ``` 3. application.yml or bootstrap.yml ``` hystrix: command: default: circuitBreaker: forceOpen: false #方法级的key "ServiceBClient#doGetFromB(String,Integer)": circuitBreaker: #设置窗口时间内的调用失败次数, 达到次数此窗口期内所有调用走fallback requestVolumeThreshold: 1 #设置熔断观察窗口的时间 sleepWindowInMilliseconds: 10000 execution: isolation: # strategy: Semaphore thread: #设置超时时间 timeoutInMilliseconds: 3000 fallback: isolation: semaphore: maxConcurrentRequests: 1 threadpool: #类级的key bs-service-b: # default: #线程池的配置 coreSize: 10 maximumSize: 10 allowMaximumSizeToDivergeFromCoreSize: true # maxQueueSize: 1 # queueSizeRejectionThreshold: 1 ribbon: ConnectTimeout: 10000 ReadTimeout: 10000 feign: hystrix: enabled: true eureka: client: registry-fetch-interval-seconds: 1 ``` 4. FeignClient ``` package com.example.a.client; import com.example.a.fallback.ServiceBFallBack; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.*; /** * Created by liuliyun-ds on 2018/6/27. */`访问服务器bs-service-b,并且有返回错误熔断处理机制` @FeignClient(name = "bs-service-b", fallback = ServiceBFallBack.class) public interface ServiceBClient { @RequestMapping(value = "/serviceB/test", method = RequestMethod.GET) String doGetFromB(@RequestParam(value = "arg") String arg, @RequestParam(value = "s") Integer s); } ``` 4. FallBack类型 ``` package com.example.a.fallback; import com.example.a.client.ServiceBClient; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.RequestParam; /** * Created by liuliyun-ds on 2018/11/26. */ @Component public class ServiceBFallBack implements ServiceBClient{ @Override`同接口方法,熔断处理机制后返回信息` public String doGetFromB(@RequestParam(value = "arg") String arg, @RequestParam(value = "s") Integer s){ return "messageFromBFallback\n"; } } ``` 5. 测试入口 ``` package com.example.a.controller; import com.example.a.client.ServiceBClient; import com.example.a.client.ServiceCClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * Created by liuliyun-ds on 2018/11/9. */ @RestController @RequestMapping("/serviceA") @RefreshScope public class AController { @Value("${test.message}") private String message; @Autowired private ServiceBClient serviceBClient; @Autowired private ServiceCClient serviceCClient; @GetMapping("/configTest") public String doGetMessage(){ // return null; return message; } @GetMapping("/test") public String doGet(String arg, Integer s, String same, Integer index){ String messageA = "messageFromA\n"; Runnable runnable = new Runnable() { @Override public void run() { String message = serviceBClient.doGetFromB(arg, s); System.out.println("+++++++++++++++++++++" + message); } }; if ("yes".equals(same)){ ExecutorService executorService = Executors.newFixedThreadPool(10); for(int i = 0; i<5; i++){ executorService.submit(runnable); } executorService.shutdown(); }else { String messageB = serviceBClient.doGetFromB(arg, s); System.out.println("========================" + messageA + messageB); return messageA + messageB; } return messageA; } } ``` ``` spring-cloud-starter-sleuth 跟踪原理:pom中依赖spring-cloud-starter-sleuth包后,每次链路请求都会添加一串追踪信息,格式是[server-name, main-traceId,sub-spanId,boolean] 第一个参数:服务结点名称; 第二个参数:一条链路唯一的ID,叫TraceID 第三个参数:链路中每一环的ID,叫做SpanID 第四个参数:是否将信息输出到Zipkin等服务收集和展示。 这种机制是如何实现的呢?我们知道Spring Framework微服务是通过http协议通信的(与之对立的是dubbo的RPC方式),所以Sleuth的实现也是基于http的,又不能影响正常的业务传递,所以能做文章的只能在http 的header上。 Sleuth会在每个请求的header上添加跟踪需求的重要信息,例如: X-B3-TraceId:对应TraceID; X-B3-SpanId:对应SpanID; X-B3-ParentSpanId:前面一环的SpanID; X-B3-Sampled:是否被选中抽样输出; X-Span-Name:工作单元名称。 x-b3-spanid x-b3-parentspanid x-b3-sampled x-b3-traceid 以上参考: 牛麦康纳 https://blog.csdn.net/yejingtao703/article/details/78064066 logback.xml 参考 作者:楠倏之语 链接:https://www.jianshu.com/p/6d6b52c7624f 來源:简书 简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。 ``` #### 使用说明 1. xxxx 2. xxxx 3. xxxx #### 参考贡献 1. 官网:[openfeign官网](http://cloud.spring.io/spring-cloud-openfeign/single/spring-cloud-openfeign.html) 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request