美文网首页
springcloud学习笔记

springcloud学习笔记

作者: 机器不能学习 | 来源:发表于2018-09-11 15:22 被阅读0次

    注册一个服务注册中心 是一个管理微服务的地方 重点是@EnableEurekaServer
    可利用端口号8761登入界面 和hadoop/mongodb/redis的管理中心相似

    @EnableEurekaServer
    @SpringBootApplication
    public class EurekaserverApplication {

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

    }

    创建一个服务提供者,当client向server注册时,它会提供一些元数据:端口号,url等,如果超时会被删除

    @SpringBootApplication
    @EnableEurekaClient
    @RestController
    public class ServiceHiApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceHiApplication.class, args);
    }
    
    @Value("${server.port}")
    String port;
    @RequestMapping("/hi")
    public String home(@RequestParam String name) {
        return "hi "+name+",i am from port:" +port;
    }
    

    }
    client的命名 类名 Service+名+Application
    在配置中的名字是真正使用时的名字(如在Feing时调用的微服务名),application.name=service-名

    ribbon是一个负载均衡客户端,可以很好的控制htt和tcp的一些行为。

    @SpringBootApplication
    @EnableDiscoveryClient
    public class ServiceRibbonApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceRibbonApplication.class, args);
    }
    
    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
    

    }@LoadBalanced可以完成负载均衡
    RestTemplate对象更是强大,它可以访问一个uri并且得到访问后返回的数据(http信息),它是spring对REST的封装。
    REST/RestTemplate https://blog.csdn.net/itguangit/article/details/80198895
    https://blog.csdn.net/itguangit/article/details/78825505

    Feign是一个web请求的工具,可以将请求指定到具体的服务上去
    Feign更轻量级的httpclient可以绑定参数访问uri
    一般用于远程调用,在feign写好调用微服务的名字,就可以在任意一处调用该微服务中的方法了
    对Feign的配置,不写就默认

    @Configuration
    public class FeignConfig {
    @Bean
    public Retryer feignRetryer() {
    return new Retryer.Default(100, SECONDS.toMillis(1), 5);
    }
    }

    指定微服务名称,和服务的方法

    @FeignClient(value = "service-hi",configuration = FeignConfig.class)
    public interface SchedualServiceHi {
    @RequestMapping(value = "/hi",method = RequestMethod.GET)
    String sayHiFromClientOne(@RequestParam(value = "name") String name);
    }

    在其他控制器中调用该微服务的方法

    @RestController
    public class HiController {
    @Autowired
    SchedualServiceHi schedualServiceHi;
    @RequestMapping(value = "/hi",method = RequestMethod.GET)
    public String sayHi(@RequestParam String name){
    return schedualServiceHi.sayHiFromClientOne(name);
    }
    }

    向服务发送请求的过程中,有些情况需要对请求的内容进行处理。例如服务端发布的服务接收的是JSON格式参数,而客户端使用的是对象,这种情况就可以使用编码器,将对象转换为JSON字符串。

    如果接口方法要求是json

    public interface PersonClient {
    @RequestLine("POST /person/create")
    @Headers("Content-Type: application/json")
    String createPerson(Person person);

    @Data
    class Person {
        Integer id;
        String name;
        Integer age;
        String message;
    }
    

    }

    那么调用该微服务方法时,先得到该类,再传参

    public class EncoderTest {
    public static void main(String[] args) {
    // 获取服务接口
    PersonClient personClient = Feign.builder()
    .encoder(new GsonEncoder())
    .target(PersonClient.class, "http://localhost:8080/");
    // 创建参数的实例
    Person person = new Person();
    person.id = 1;
    person.name = "Angus";
    person.age = 30;
    String response = personClient.createPerson(person);
    System.out.println(response);
    }
    }

    编码器是对请求的内容进行处理,解码器则会对服务响应的内容进行处理,例如解析响应的JSON或者XML字符串,转换为我们所需要的对象,在代码中通过以下的代码片断设置解码器:
    使用.decoder()进行设置,并且在接口处@Headers要设置

    Hystrix:防止某个服务不可用殃及到所偶服务不可用

    资源隔离模式:1.线程池隔离模式,用多个线程池,高流量时处理不完的数据可存在线程池中慢慢处理
    2.信号隔离,严格计数当前线程,当高流量时线程超过预定值直接不处理
    设置

    https://www.cnblogs.com/gaoyanqing/p/7470085.html
    public class CommandUsingSemaphoreIsolation extends HystrixCommand<String> {
    private final int id;
    private long start,end ;

      public CommandUsingSemaphoreIsolation(int id) {
          super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
                  // since we're doing an in-memory cache lookup we choose SEMAPHORE isolation
                  .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                         .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE) //设置使用信号量隔离策略
                                 .withExecutionIsolationSemaphoreMaxConcurrentRequests(3)  //设置信号量隔离时的最大并发请求数
                                 .withFallbackIsolationSemaphoreMaxConcurrentRequests(5)     //设置fallback的最大并发数
                         .withExecutionTimeoutInMilliseconds(300)));   //设置超时时间
         this.id = id;
         this.start = System.currentTimeMillis();
     }
    
     @Override
     protected String run() throws InterruptedException {
         // a real implementation would retrieve data from in memory data structure
         TimeUnit.MILLISECONDS.sleep(id*30);
         System.out.println("running normal, id="+id);
         return "ValueFromHashMap_" + id;
     }
    
     @Override
     protected String getFallback(){
         System.out.println(" fallback, id="+id);
         return "fallback:"+id;
     }
    

    }

    线程池隔离中,发起请求的线程和真实执行的线程不是同一个线程,使用信号量隔离时,它们是同一个线程

    降级方案:fallback:当失败时我们会用候选方案:降级方案

    @SpringBootApplication
    @EnableEurekaClient
    @EnableDiscoveryClient
    @EnableHystrix //在微服务中允许使用
    public class ServiceRibbonApplication {
    public static void main(String[] args) {
    SpringApplication.run( ServiceRibbonApplication.class, args );
    }

    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
    

    }

    @Service
    public class HelloService {

    @Autowired
    RestTemplate restTemplate;
    
    @HystrixCommand(fallbackMethod = "hiError")     //注解表示开启
    public String hiService(String name) {
        return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);
    }
    public String hiError(String name) {
        return "hi,"+name+",sorry,error!";
    }
    

    }

    Feign中使用断路器

    @FeignClient(value = "service-hi",fallback = SchedualServiceHiHystric.class)
    public interface SchedualServiceHi {
    @RequestMapping(value = "/hi",method = RequestMethod.GET)
    String sayHiFromClientOne(@RequestParam(value = "name") String name);
    }

    @Component
    public class SchedualServiceHiHystric implements SchedualServiceHi {
    @Override
    public String sayHiFromClientOne(String name) {
    return "sorry "+name;
    }
    }

    熔断器机制:https://www.cnblogs.com/small-k/p/8149227.html

    请求合并:将多次请求变为一次,减少io的消耗,增加平均延迟
    1、必须继承HystrixCollapser类,

    2、实现以下方法:

    getRequestArgument: 返回请求参数对象

    createCommand : 返回BatchCommand

    mapResponseToRequests:实现Response和Request的映射

    3、创建对应的BatchCommand类:批量请求的具体实现
    http://blog.didispace.com/spring-cloud-hystrix-request-collapse

    网关zuul:官方文档http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#_router_and_filter_zuul
    是一个路由和负载均衡器。它可以通过映射来完成服务器的访问,类似于php框架的路由器

    @SpringBootApplication
    @EnableZuulProxy // 启动路由
    publicclass ZuulApplication {
    publicstaticvoid main(String[] args) {

        SpringApplication.run(ZuulApplication.class, args);
    }
    

    }

    它可以用过yml文件来书写规则
    zuul:
    routes:
    ignoredServices: '' //需要忽略的微服务
    ignoredPatterns: /
    /admin/* //需要忽略的地址
    users:
    //下面是参数
    path: /myusers/** //外来访问的地址,只要是这个格式就命中
    users: /myusers/** //users是微服务名 后面跟自定义路由
    url: https://downstream //命中就进入该网站
    serviceId: users_service //指定转发给哪个微服务
    更多用法参照 http://blog.51cto.com/1754966750/1958422

    路由熔断 指定熔断某个服务
    如果微服务下线了,针对每个微服务,都需要回复一个中文提示,而不是报异常

    @Component
    public class ConsumerFallbackProvider implements ZuulFallbackProvider {
    @Override
    public String getRoute() {
    // 表明是为哪个微服务提供回退
    return "tcloud-user-consumer";
    }

    @Overrid
    public ClientHttpResponse fallbackResponse() {
    return new ClientHttpResponse() {
    @Override
    public HttpStatus getStatusCode() throws IOException {
    // fallback时的状态码
    return HttpStatus.OK;
    }

      @Override
      public int getRawStatusCode() throws IOException {
        // 数字类型的状态码,本例返回的其实就是200,详见HttpStatus
        return this.getStatusCode().value();
      }
    
      @Override
      public String getStatusText() throws IOException {
        // 状态文本,本例返回的其实就是OK,详见HttpStatus
        return this.getStatusCode().getReasonPhrase();
      }
    
      @Override
      public void close() {
      }
    
      @Override
      public InputStream getBody() throws IOException {
        // 响应体
        return new ByteArrayInputStream("tcloud-user-consumer微服务不可用,请稍后再试。".getBytes());
      }
    
      @Override
      public HttpHeaders getHeaders() {
        // headers设定
        HttpHeaders headers = new HttpHeaders();
        MediaType mt = new MediaType("application","json", Charset.forName("UTF-8"));
        headers.setContentType(mt);
        return headers;
      }
    };}}

    相关文章

      网友评论

          本文标题:springcloud学习笔记

          本文链接:https://www.haomeiwen.com/subject/yheugftx.html