springcloud用法
 
 
使用springcloud搭建微服务肯定要在父工程下面编写子工程
 
一.搭建eureka注册中心
 
1.    创建maven项目(在springboot项目下建立子工程eureka-server)
 
2.    导入坐标
| 
 <dependencies> 
      <dependency> 
          <groupId>org.springframework.cloud</groupId> 
          <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> 
      </dependency> 
  </dependencies> 
   | 
 
 
3.   
创建引导类
 
@SpringBootApplication 
  @EnableEurekaServer  //添加注解 表名服务,声明这个应用时EurekaServer 
  public class EurekaManager { 
    public static void main(String[] args) { 
        SpringApplication.run(EurekaManager.class,args); 
    } 
} 
  
 | 
 
4.    编写配置文件
编写application.yml文件
server: 
  port: 10086 
  spring: 
  application: 
    name: eureka-server  #自己注册的serviceId,即注册名称 
 
  eureka: 
  client: 
    service-url: 
      defaultZone: http://127.0.0.1:10086/eureka 
 
    register-with-eureka: true   #注册自己,默认为true 
    fetch-registry: true  #拉取服务,默认为true 
  
 | 
 
5.    效果截图
 
 
 
 
二.搭建提供者,user-service
提供者user-service对于注册中心而言还是客户端
1.    创建maven工程user-service
2.    导入坐标
 
 
<!--添加坐标--> 
  <dependencies> 
    <dependency> 
        <groupId>org.springframework.boot</groupId> 
        <artifactId>spring-boot-starter-web</artifactId> 
    </dependency> 
   
    <dependency> 
        <groupId>mysql</groupId> 
        <artifactId>mysql-connector-java</artifactId> 
    </dependency> 
   
    <dependency> 
        <groupId>tk.mybatis</groupId> 
        <artifactId>mapper-spring-boot-starter</artifactId> 
    </dependency> 
   
      <dependency> 
        <groupId>org.springframework.cloud</groupId> 
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> 
    </dependency> 
   
  </dependencies> 
  
 | 
 
3.    编写启动类
 
package com.ahd; 
   
  import org.springframework.boot.SpringApplication; 
  import org.springframework.boot.autoconfigure.SpringBootApplication; 
  import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 
  import org.springframework.context.annotation.Bean; 
  import org.springframework.web.client.RestTemplate; 
  import tk.mybatis.spring.annotation.MapperScan; 
   
  @SpringBootApplication 
@EnableDiscoveryClient  //使用这个注解 针对所有注册中心, 
//@EnableEurekaClient  这个注解只针对eureka的注册中心 
  @MapperScan("com.ahd.mapper") 
  public class UserServiceApplication { 
    public static void main(String[] args) { 
        SpringApplication.run(UserServiceApplication.class,args); 
    } 
   
} 
  
 | 
 
 
4. 编写配置文件
 
server: 
  port: 8181 
  spring: 
  datasource: 
    driver-class-name: com.mysql.jdbc.Driver 
    url: jdbc:mysql://127.0.0.1:3306/cloud_test 
    username: root 
    password: 123456 
  application: 
    name: user-service 
  eureka: 
  client: 
    service-url: 
      defaultZone: http://127.0.0.1:10086/eureka 
    register-with-eureka: true  #默认的 
    fetch-registry: true  #默认的 
  
 | 
 
5. 编写具体业务逻辑
略
 
6.    编写controller层代码
 
package com.ahd.controller; 
   
  import com.ahd.pojo.User; 
  import com.ahd.service.UserService; 
  import org.springframework.beans.factory.annotation.Autowired; 
  import org.springframework.web.bind.annotation.GetMapping; 
  import org.springframework.web.bind.annotation.PathVariable; 
  import org.springframework.web.bind.annotation.RestController; 
   
  @RestController 
  public class UserController { 
    @Autowired 
    private UserService userService; 
   
    @GetMapping("/user/{id}") 
    public User findById(@PathVariable("id") Long id){ 
        return userService.findById(id); 
    } 
} 
  
 | 
 
 
三.负载均衡Ribbon
当消费方 向 提供方发送请求,可能有多个提供方,这时候就需要考虑向那个提供方发送请求了
 
1.    创建消费者maven工程
consumer
2.    导入坐标
eureka中已经继承了ribbon的坐标,不需要导入,展示一下所有坐标
<dependencies> 
    <dependency> 
        <groupId>org.springframework.cloud</groupId> 
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> 
    </dependency> 
   
    <dependency> 
        <groupId>org.springframework.boot</groupId> 
        <artifactId>spring-boot-starter-web</artifactId> 
    </dependency> 
  </dependencies> 
  
 | 
 
3.    编写引导类
 
package com.and; 
   
  import org.springframework.boot.SpringApplication; 
  import org.springframework.boot.autoconfigure.SpringBootApplication; 
  import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 
  import org.springframework.cloud.client.loadbalancer.LoadBalanced; 
  import org.springframework.context.annotation.Bean; 
  import org.springframework.web.client.RestTemplate; 
   
  @SpringBootApplication 
@EnableDiscoveryClient  //使用这个注解 针对所有注册中心, 
//@EnableEurekaClient  这个注解只针对eureka的注册中心 
  public class ConsumerApplication { 
    public static void main(String[] args) { 
        SpringApplication.run(ConsumerApplication.class,args); 
    } 
   
    @Bean 
    @LoadBalanced 
    public RestTemplate getTemplate(){ 
        return new RestTemplate(); 
    } 
} 
  
 | 
 
 
4.    编写配置文件application.yml文件
 
server: 
  port: 8180 
  spring: 
  application: 
    name: consumer 
  eureka: 
  client: 
    fetch-registry: true  #默认的,可以不写 
    service-url: 
      defaultZone: http://127.0.0.1:10086/eureka 
    register-with-eureka: true #默认的,可以不写 
  ribbon: 
  eager-load: 
    enabled: true  #开启饥饿加载,默认是不开启,采用懒加载 
    clients: user-service  #需要指定是哪个提供方 
  user-service: 
  ribbon: 
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule  #配置负载均衡的策略,默认是轮训,这里是随机 
  
 | 
 
5.    编写controller层(发送请求的类)
 
package com.and.controller; 
   
  import com.and.pojo.User; 
  import org.springframework.beans.factory.annotation.Autowired; 
  import org.springframework.cloud.client.discovery.DiscoveryClient; 
  import org.springframework.web.bind.annotation.GetMapping; 
  import org.springframework.web.bind.annotation.PathVariable; 
  import org.springframework.web.bind.annotation.RestController; 
  import org.springframework.web.client.RestTemplate; 
   
   
  @RestController 
  public class ConsumerController { 
    @Autowired 
    private RestTemplate restTemplate; 
    @Autowired 
    private DiscoveryClient discoveryClient; 
    @GetMapping("/user/{id}") 
    public User getUserFromService(@PathVariable("id") Long id){ 
       /*不使用负载均衡时使用的方法,使用ribbon负载均衡不需要自己选择哪个提供者 
       List<ServiceInstance> instances = discoveryClient.getInstances("USER-SERVICE"); 
        ServiceInstance serviceInstance = instances.get(0); 
   
        String host = serviceInstance.getHost(); 
        int port = serviceInstance.getPort(); 
   
        String url = String.format("http://%s:%d/user/%d", host, port, id);*/ 
       String url="http://user-service/user/"+id; 
        return restTemplate.getForObject(url,User.class); 
    } 
} 
  
 | 
 
 
四.Hystrix-服务降级
 
两大主要作用:
线程隔离,服务降级
         服务熔断
一般作用于消费者
 
1.    引入坐标
在源consumer基础上添加一下坐标即可
| 
 <dependency> 
    <groupId>org.springframework.cloud</groupId> 
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> 
</dependency> 
 | 
 
完整坐标:
<dependencies> 
    <dependency> 
        <groupId>org.springframework.cloud</groupId> 
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> 
    </dependency> 
   
    <dependency> 
        <groupId>org.springframework.boot</groupId> 
        <artifactId>spring-boot-starter-web</artifactId> 
    </dependency> 
   
    <dependency> 
        <groupId>org.springframework.cloud</groupId> 
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> 
    </dependency> 
   
   
  </dependencies> 
  
 | 
 
2.    配置引导类
 
package com.and; 
   
  import org.springframework.boot.SpringApplication; 
  import org.springframework.boot.autoconfigure.SpringBootApplication; 
  import org.springframework.cloud.client.SpringCloudApplication; 
  import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; 
  import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 
  import org.springframework.cloud.client.loadbalancer.LoadBalanced; 
  import org.springframework.cloud.netflix.hystrix.EnableHystrix; 
  import org.springframework.context.annotation.Bean; 
  import org.springframework.web.client.RestTemplate; 
   
  /*@SpringBootApplication 
@EnableDiscoveryClient  //使用这个注解 针对所有注册中心, 
//@EnableEurekaClient  这个注解只针对eureka的注册中心 
@EnableCircuitBreaker  这个是hystrix的注解*/ 
  @SpringCloudApplication  //代表上面的三个注解 
  public class ConsumerApplication { 
    public static void main(String[] args) { 
        SpringApplication.run(ConsumerApplication.class,args); 
    } 
   
    @Bean 
    @LoadBalanced 
    public RestTemplate getTemplate(){ 
        return new RestTemplate(); 
    } 
} 
  
 | 
 
3.    改写Controller类
方式一:针对方法服务降级
 
package com.and.controller; 
   
  import com.and.pojo.User; 
  import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; 
  import org.springframework.beans.factory.annotation.Autowired; 
  import org.springframework.cloud.client.discovery.DiscoveryClient; 
  import org.springframework.web.bind.annotation.GetMapping; 
  import org.springframework.web.bind.annotation.PathVariable; 
  import org.springframework.web.bind.annotation.RestController; 
  import org.springframework.web.client.RestTemplate; 
   
   
  @RestController 
  public class ConsumerController { 
    @Autowired 
    private RestTemplate restTemplate; 
    @Autowired 
    private DiscoveryClient discoveryClient; 
    @GetMapping("/user/{id}") 
    @HystrixCommand(fallbackMethod = "fallBack") 
    public String getUserFromService(@PathVariable("id") Long id){ 
       String url="http://user-service/user/"+id; 
        return restTemplate.getForObject(url,User.class).toString(); 
    } 
   
   
      public String fallBack(Long id){//返回值和参数必须和对应方法保持一致 
        return "网络开了一个小差"; 
    } 
} 
  
 | 
 
方式二:针对类进行服务降级
 
package com.and.controller; 
   
  import com.and.pojo.User; 
  import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties; 
  import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; 
  import org.springframework.beans.factory.annotation.Autowired; 
  import org.springframework.cloud.client.discovery.DiscoveryClient; 
  import org.springframework.web.bind.annotation.GetMapping; 
  import org.springframework.web.bind.annotation.PathVariable; 
  import org.springframework.web.bind.annotation.RestController; 
  import org.springframework.web.client.RestTemplate; 
   
   
  @RestController 
  @DefaultProperties(defaultFallback = "quanjuFallBack") 
  public class ConsumerController { 
    @Autowired 
    private RestTemplate restTemplate; 
    @Autowired 
    private DiscoveryClient discoveryClient; 
    @GetMapping("/user/{id}") 
    @HystrixCommand 
    public String getUserFromService(@PathVariable("id") Long id){ 
       String url="http://user-service/user/"+id; 
        return restTemplate.getForObject(url,User.class).toString(); 
    } 
   
   
    public String fallBack(Long id){//返回值和参数必须和对应方法保持一致 
        return "网络开了一个小差"; 
    } 
   
    public String quanjuFallBack(){ //针对多个方法,不需要配置参数 
        return "全局配置:网络开了一个小差"; 
    } 
} 
  
 | 
 
4.    修改配置文件application.yml
 
server: 
  port: 8180 
  spring: 
  application: 
    name: consumer 
  eureka: 
  client: 
    fetch-registry: true  #默认的,可以不写 
    service-url: 
      defaultZone: http://127.0.0.1:10086/eureka 
    register-with-eureka: true #默认的,可以不写 
  ribbon: 
  eager-load: 
    enabled: true  #开启饥饿加载,默认是不开启,采用懒加载 
    clients: user-service  #需要指定是哪个提供方 
  user-service: 
  ribbon: 
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule  #配置负载均衡的策略,默认是轮训,这里是随机 
  hystrix: 
  command: 
    default: 
      execution: 
        isolation: 
          thread: 
            timeoutInMilliseconds: 2000  #超时时间配置,超过这个时间请求还没有响应,服务降级 
  
 | 
 
配置文件响应时间修改为两秒也是为了测试
5.    运行结果
为了获取测试结果,在提供方进行了两秒的睡眠
 
 
 
最终结果效果图:
 
 
 
五.Hystrix-服务熔断
这个东西好搞,和服务降级配置相同
 
@GetMapping("/user/{id}") 
  @HystrixCommand 
  public String getUserFromService(@PathVariable("id") Long id){ 
      if(id==1){ 
        throw new RuntimeException(); 
    }//方便进行测试 
   
   String url="http://user-service/user/"+id; 
    return restTemplate.getForObject(url,User.class).toString(); 
}
  
 | 
 
 
熔断器的默认触发阈值是20次请求,不好触发。休眠时间时5秒,时间太短,不易观察,为了测试方便,我们可以通过配置修改熔断策略:
circuitBreaker.requestVolumeThreshold=10
circuitBreaker.sleepWindowInMilliseconds=10000
circuitBreaker.errorThresholdPercentage=50
 
解读:
- requestVolumeThreshold:触发熔断的最小请求次数,默认20
 
- sleepWindowInMilliseconds:休眠时长,默认是5000毫秒
 
- errorThresholdPercentage:触发熔断的失败请求最小占比,默认50%
 
在类中进行配置,配置方式
@HystrixCommand(commandProperties={@HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value="10"), 
       @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value="10000"), 
        @HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value="50") 
        })
  
 | 
 
六.feign
 
feign :伪装
 
减少重复代码
 
1.    导入坐标
添加坐标:
<dependency> 
    <groupId>org.springframework.cloud</groupId> 
    <artifactId>spring-cloud-starter-openfeign</artifactId> 
  </dependency> 
  
 | 
 
完整坐标:
<dependencies> 
    <dependency> 
        <groupId>org.springframework.cloud</groupId> 
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> 
    </dependency> 
   
    <dependency> 
        <groupId>org.springframework.boot</groupId> 
        <artifactId>spring-boot-starter-web</artifactId> 
    </dependency> 
   
    <dependency> 
        <groupId>org.springframework.cloud</groupId> 
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> 
    </dependency> 
   
    <dependency> 
        <groupId>org.springframework.cloud</groupId> 
        <artifactId>spring-cloud-starter-openfeign</artifactId> 
    </dependency> 
   
   
  </dependencies> 
  
 | 
 
2.    修改引导类(添加feign的注解)
 
package com.and; 
   
  import org.springframework.boot.SpringApplication; 
  import org.springframework.boot.autoconfigure.SpringBootApplication; 
  import org.springframework.cloud.client.SpringCloudApplication; 
  import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; 
  import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 
  import org.springframework.cloud.client.loadbalancer.LoadBalanced; 
  import org.springframework.cloud.netflix.hystrix.EnableHystrix; 
  import org.springframework.cloud.openfeign.EnableFeignClients; 
  import org.springframework.context.annotation.Bean; 
  import org.springframework.web.client.RestTemplate; 
   
  /*@SpringBootApplication 
@EnableDiscoveryClient  //使用这个注解 针对所有注册中心, 
//@EnableEurekaClient  这个注解只针对eureka的注册中心 
@EnableCircuitBreaker  这个是hystrix的注解*/ 
  @SpringCloudApplication  //代表上面的三个注解 
  @EnableFeignClients  //开启feign功能 
  public class ConsumerApplication { 
    public static void main(String[] args) { 
        SpringApplication.run(ConsumerApplication.class,args); 
    } 
   
    @Bean 
    @LoadBalanced 
    public RestTemplate getTemplate(){ 
        return new RestTemplate(); 
    } 
} 
  
 | 
 
 
3.    编写feign的接口
feign支持springmvc所有的注解
package com.and.feign; 
   
  import com.and.pojo.User; 
  import org.springframework.cloud.openfeign.FeignClient; 
  import org.springframework.web.bind.annotation.GetMapping; 
  import org.springframework.web.bind.annotation.PathVariable; 
   
  @FeignClient("user-service") 
  public interface UserClient { 
    @GetMapping("/user/{id}") //这里的返回结果和 url地址一定要和提供方保持一致 
    User getUserFromService(@PathVariable("id") Long id); 
} 
  
 | 
 
4.    修改controller层代码
 
package com.and.controller; 
   
  import com.and.feign.UserClient; 
  import com.and.pojo.User; 
  import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties; 
  import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; 
  import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; 
  import org.springframework.beans.factory.annotation.Autowired; 
  import org.springframework.cloud.client.discovery.DiscoveryClient; 
  import org.springframework.web.bind.annotation.GetMapping; 
  import org.springframework.web.bind.annotation.PathVariable; 
  import org.springframework.web.bind.annotation.RestController; 
  import org.springframework.web.client.RestTemplate; 
   
   
  @RestController 
@DefaultProperties(defaultFallback = "quanjuFallBack") 
  public class ConsumerController { 
    @Autowired 
    private RestTemplate restTemplate; 
    @Autowired 
    private DiscoveryClient discoveryClient; 
      @Autowired 
    private UserClient userClient; 
    @GetMapping("/user/{id}") 
    @HystrixCommand 
    public String getUserFromService(@PathVariable("id") Long id){ 
        return userClient.getUserFromService(id).toString(); 
    } 
   
   
    public String fallBack(Long id){//返回值和参数必须和对应方法保持一致 
        return "网络开了一个小差"; 
    } 
   
    public String quanjuFallBack(){ //针对多个方法,不需要配置参数 
        return "全局配置:网络开了一个小差"; 
    } 
} 
  
 | 
5.    feign其他拓展
feign继承了ribbon,不需要再单独配置,也不需要再配置RestTemplate,
 
Fegin内置的ribbon默认设置了请求超时时长,默认是1000ms,我们可以通过手动配置来修改这个超时时长:
ribbon:
  ReadTimeout: 2000 # 读取超时时长
  ConnectTimeout: 1000 # 建立链接的超时时长
 
,因为ribbon内部有重试机制,一旦超时,会自动重新发起请求。如果不希望重试,可以添加配置:
ribbon:
  ReadTimeout: 2000 # 数据通信超时时长
  ConnectTimeout: 500 # 连接超时时长  
  MaxAutoRetries: 0 # 当前服务器的重试次数
  MaxAutoRetriesNextServer: 1 # 重试多少次服务
  OkToRetryOnAllOperations: false # 是否对所有的请求方式都重试
 
另外,hystrix的超时时间,应该比重试的总时间要大,比如当前案例中,应该配 大于2500*2 = 5000
 
6.   
feign内置hystrix
 
只不过,默认情况下是关闭的。我们需要通过下面的参数来开启:
feign:
  hystrix:
    enabled: true # 开启Feign的熔断功能
 
但是,Feign中的Fallback配置不像Ribbon中那样简单了
1)首先,我们要定义一个类,实现刚才编写的UserFeignClient,作为fallback的处理类
@Component
public class UserClientFallback implements UserClient {
    @Override
    public User queryById(Long id) {
        User user = new User();
        user.setId(id);
        user.setName("用户查询出现异常!");
        return user;
   
}
}
 
2)然后在UserFeignClient中,指定刚才编写的实现类
@FeignClient(value = "user-service", fallback = UserFeignClientFallback.class)
public interface UserClient {
?
    @GetMapping("/user/{id}")
    User queryById(@PathVariable("id") Long id);
}
?
 
 
7.   
feign请求压缩
Spring Cloud Feign 支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。通过下面的参数即可开启请求与响应的压缩功能:
feign:
  compression:
    request:
      enabled: true # 开启请求压缩
    response:
      enabled: true # 开启响应压缩
 
同时,我们也可以对请求的数据类型,以及触发压缩的大小下限进行设置:
feign:
  compression:
    request:
      enabled: true # 开启请求压缩
      mime-types: text/html,application/xml,application/json # 设置压缩的数据类型
      min-request-size: 2048 # 设置触发压缩的大小下限
 
注:上面的数据类型、压缩大小下限均为默认值。
 
 
8.    feign日志级别
前面讲过,通过logging.level.xx=debug来设置日志级别。然而这个对Fegin客户端而言不会产生效果。因为@FeignClient注解修改的客户端在被代理时,都会创建一个新的Fegin.Logger实例。我们需要额外指定这个日志的级别才可以。
1)设置cn.itcast包下的日志级别都为debug
logging:
  level:
   
cn.itcast: debug
 
2)编写配置类,定义日志级别
@Configuration
public class FeignConfig {
    @Bean
    Logger.Level feignLoggerLevel(){
        return Logger.Level.FULL;
   
}
}
 
这里指定的Level级别是FULL,Feign支持4种级别:
 
- NONE:不记录任何日志信息,这是默认值。
 
- BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
 
- HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
 
- FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。
 
3)在FeignClient中指定配置类:
@FeignClient(value = "user-service", fallback = UserClientFallback.class, configuration = FeignConfig.class)
public interface UserClient {
    @GetMapping("/user/{id}")
    User queryById(@PathVariable("id") Long id);
}
 
4)重启项目,即可看到每次访问的日志:
 
 
七.Zuul网关
网关的核心功能是:过滤和路由
 
1.   
新建maven工程
略,zuul-server
2.   
配置依赖坐标
 
| 
 <dependencies> 
      <dependency> 
          <groupId>org.springframework.cloud</groupId> 
          <artifactId>spring-cloud-starter-netflix-zuul</artifactId> 
      </dependency> 
      <dependency> 
          <groupId>org.springframework.cloud</groupId> 
          <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> 
      </dependency> 
  </dependencies> 
  
   | 
 
 
3.   
编写启动类
 
package com.ahd; 
   
  import org.springframework.boot.SpringApplication; 
  import org.springframework.boot.autoconfigure.SpringBootApplication; 
  import org.springframework.cloud.netflix.zuul.EnableZuulProxy; 
   
  @SpringBootApplication 
  @EnableZuulProxy //开启zuul网关 
  public class ZuulApplication { 
    public static void main(String[] args) { 
        SpringApplication.run(ZuulApplication.class,args); 
    } 
} 
  
 | 
 
4.    编写配置
application.yml
server: 
  port: 10010 
  spring: 
  application: 
    name: zuul-server 
  #编写路由规则 
#user-service: 
#  routes: 
#    path: /user-service/**  #这里是映射路径 
#    url: http://127.0.0.1:8181 #映射路径对应的实际url地址 
#如果配置了eureka,上面的代码可以写成 
#user-service: 
#  routes: 
#    path: /user-service/**  #这里是映射路径 
#    serviceId: user-service #映射路径对应的实际url地址 
   
  user-service: /user-service/**  #如果配置了eureka,上面代码可以简写成这行,这行也可以不写 
  eureka: 
  client: 
    service-url: 
      defaul                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      tZone: http://127.0.0.1:10086/eureka 
  
 | 
 
 
5.    禁用路由规则
默认情况下,一切服务的映射路径就是服务名本身。
a)       例如服务名为:user-service,则默认的映射路径就是:/user-service/**
也就是说,刚才的映射规则我们完全不配置也是OK的,不信就试试看。
如果想要禁用某个路由规则,可以这样:
zuul:
  ignored-services:
    - user-service
    - consumer
 
 
6.    路由前缀
 
配置示例:
zuul:
  prefix: /api # 添加路由前缀
  routes:
   
user-service: /user-service/** # 这里是映射路径
 
我们通过zuul.prefix=/api来指定了路由的前缀,这样在发起请求时,路径就要以/api开头。
路径/api/user-service/user/1将会被代理到/user-service/user/1
忽略路由前缀:
zuul:
  prefix: /api
  routes:
   
user-service:
     
path: /user/**
     
serviceId: user-service
     
strip-prefix: false # 是否在转发时,去除路由前缀,这里不去除,映射路径中的user就会继续转发
 
此时,只需要访问:http://localhost:10010/api/user/1
7.   
过滤器
Zuul作为网关的其中一个重要功能,就是实现请求的鉴权。而这个动作我们往往是通过Zuul提供的过滤器来实现的。
ZuulFilter是过滤器的顶级父类。在这里我们看一下其中定义的4个最重要的方法:
public abstract ZuulFilter implements IZuulFilter{
?
    abstract public String filterType();
?
    abstract public int filterOrder();
    
    boolean shouldFilter();// 来自IZuulFilter
?
    Object run() throws ZuulException;// IZuulFilter
}
 
filterType:返回字符串,代表过滤器的类型。包含以下4种: 
pre:请求在被路由之前执行
route:在路由请求时调用
post:在routing和errror过滤器之后调用
error:处理请求时发生错误调用
filterOrder:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高。 
shouldFilter:返回一个Boolean值,判断该过滤器run方法是否需要执行。返回true执行,返回false不执行。 
run:过滤器的具体业务逻辑 
 
8.    自定义过滤器
自定义过滤器只需要继承ZuulFilter抽象类,实现四个方法,交给spring管理
| 
 @Component 
public class LoginFilter extends ZuulFilter { 
    @Override 
    public String filterType() { 
        return FilterConstants.PRE_TYPE; 
    } 
  
    @Override 
    public int filterOrder() { 
        return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1; 
    } 
  
    @Override 
    public boolean shouldFilter() { 
        return true; 
    } 
  
    @Override 
    public Object run() throws ZuulException { 
        // 获取请求上下文 
        RequestContext ctx = RequestContext.getCurrentContext(); 
        // 获取request对象 
        HttpServletRequest request = ctx.getRequest(); 
        // 获取请求参数 
        String token = request.getParameter("access-token"); 
        // 判断是否存在 
        if(StringUtils.isBlank(token)){ 
            // 不存在,未登录,拦截 
            ctx.setSendZuulResponse(false); 
            // 设置返回状态码 
            ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value()); 
        } 
        return null; 
    } 
} 
 | 
 
9.    负载均衡和熔断
Zuul中默认就已经集成了Ribbon负载均衡和hystrix熔断机制。但是所有的超时策略都是走的默认值,比如熔断超时时间只有1S,很容易就触发了。因此建议我们手动进行配置:
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 6000
ribbon:
  ConnectTimeout: 1000
  ReadTimeout: 2000
  MaxAutoRetries: 0
  MaxAutoRetriesNextServer: 1
 
10.              zuul的高可用
启动多个Zuul服务,自动注册到Eureka,形成集群。如果是服务内部访问,你访问Zuul,自动负载均衡,没问题。
但是,Zuul更多是外部访问,PC端、移动端等。他们无法通过Eureka进行负载均衡,那么该怎么办?
此时,我们会使用其它的服务网关,来对Zuul进行代理。比如:Nginx
Eureka、Ribbon、hystrix、Feign、Zuul
spring-cloud-config:统一配置中心,自动去Git拉取最新的配置,缓存。使用Git的Webhook钩子,去通知配置中心,说配置发生了变化,配置中心会通过消息总线去通知所有的微服务,更新配置。
spring-cloud-bus:消息总线
Spring-cloud-stream:消息通信
spring-cloud-hystrix-dashboard:容错统计,形成图形化界面
spring-cloud-sleuth:链路追踪 结合Zipkin
 
springcloud用法
原文:https://www.cnblogs.com/aihuadung/p/11593303.html