目录java
pom.xmlmysql
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.offcn</groupId> <artifactId>APartenProject</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <properties> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
新建子模块 eureka-server01git
pom.xmlgithub
<parent> <artifactId>APartenProject</artifactId> <groupId>com.offcn</groupId> <version>1.0-SNAPSHOT</version> </parent> <groupId>com.offcn</groupId> <artifactId>eureka-server01</artifactId> <version>0.0.1-SNAPSHOT</version> <name>eureka-server01</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Greenwich.SR2</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
配置 application.ymlweb
#内置的tomcat服务启动监听端口号 server: # port: 8888 port: 10086 #应用名称 spring: application: name: eureka-server #EurekaServer配置 eureka: client: # register-with-eureka: false #此EurekaServer再也不注册到其余的注册中心 # fetch-registry: false #再也不从其余中心中心拉取服务器信息 service-url: #defaultZone: http://localhost:${server.port}/eureka #注册中心访问地址 defaultZone: http://localhost:10087/eureka #指向另一台Eureka服务器 server: enable-self-preservation: false # Eureka开启自动保护模式 eviction-interval-timer-in-ms: 4000
为启动类添加注解spring
@SpringBootApplication // 开启 EurekaServer @EnableEurekaServer public class EurekaServer01Application { public static void main(String[] args) { SpringApplication.run(EurekaServer01Application.class, args); }}
和 eureka-server01 同样,新建一个子模块eureka-server02,只改一下配置文件 application.yml,其它保持一致。sql
server: port: 10087 spring: application: name: eureka-server eureka: server: enable-self-preservation: false eviction-interval-timer-in-ms: 4000 client: service-url: defaultZone: http://localhost:10086/eureka
运行两个服务器 http://localhost:10086/ 和 http://localhost:10087/ 均可以数据库
新建子模块 userprovider01bootstrap
pom.xml后端
<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.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
application.yml
server: port: 8001 spring: application: name: userprovider datasource: url: jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8 username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update show-sql: true #必定注意eureka与spring属于平级 注意格式 eureka: client: service-url: defaultZone: http://localhost:10086/eureka/,http://localhost:10087/eureka/ # 数据 ProviderVersion: UserProvider:0.02V
建立实体类User
@Entity @Data @NoArgsConstructor @AllArgsConstructor public class User { @Id @GeneratedValue private Long id; @Column(name="name",nullable = true,length = 200) private String name; @Column(name = "age",nullable = true,length = 4) private Integer age; }
UserDao 实现 JpaRepository<User, Long>,建立UserService、UserServiceImpl、UserController(RESTful风格)
// UserController @RestController @RequestMapping("/user") public class UserController { @Autowired UserService userService; @Value("${ProviderVersion}") private String ProviderVersion; @GetMapping("/getall") @ApiOperation(value = "获取所有用户信息", notes = "获取所有用户信息") public Map<String,Object> getUsers() { Map<String,Object> map=new HashMap<>(); List<User> list = userService.getUserList(); map.put("list", list); map.put("ProviderVersion", ProviderVersion); return map; } ...... }
启动类添加注解 @EnableDiscoveryClient
新建子模块 userprovider02,除了 application.yml 和 UserController的getAll方法有些差异外,其它所有同样
server: port: 8002 spring: application: name: userprovider datasource: url: jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8 username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update show-sql: true #必定注意eureka与spring属于平级 注意格式 eureka: client: service-url: defaultZone: http://localhost:10086/eureka/,http://localhost:10087/eureka/
// UserController 中的getUser方法中 ProviderVersion 的值与 UserProvider01项目有所区别(ProviderVersion: UserProvider:0.02V),这是为了后面负载均衡的时候看出差异。 @GetMapping("/getall") public Map<String,Object> getUsers() { Map<String,Object> map=new HashMap<>(); List<User> list = userService.getUserList(); map.put("list", list); String ProviderVersion="用户服务UserProvdier002:0.01V"; map.put("ProviderVersion", ProviderVersion); return map; }
运行两个提供者
新建子模块 userweb01
pom.xml
<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.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>4.2.1</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
配置 application.yml
server: port: 9001 spring: thymeleaf: cache: false application: name: userweb01 eureka: client: service-url: defaultZone: http://localhost:10086/eureka/,http://localhost:10087/eureka/
修改启动类
@SpringBootApplication @EnableDiscoveryClient public class Userweb01Application { public static void main(String[] args) { SpringApplication.run(Userweb01Application.class, args); } @Bean public RestTemplate getRestTemplate() { return new RestTemplate(); } }
新建 User,UserController,UserService,UserSerivceImpl
// UserController.java // 由于使用了 thymeleaf,因此须要转发到相应模版,使用 Model 携带数据 @Controller public class UserController { @Autowired UserService userService; @GetMapping("/") public String getUserList(Model model){ Map map = userService.getUserMap(); List<User> list=(List<User>) map.get("list"); model.addAttribute("page", list); model.addAttribute("ProviderVersion", map.get("ProviderVersion")); return "user/list"; } ...... }
// UserSerivceImpl.java @Service public class UserServiceImpl implements UserService { //远程服务调用客户端 @Autowired RestTemplate restTemplate; //Eureka客户端 @Autowired DiscoveryClient discoveryClient; /*** * 经过客户端负载均衡器获取生产者服务器基础地址 * @return */ public String getServerUrl() { //经过客户端调用器查找指定服务 List<ServiceInstance> instList = discoveryClient.getInstances("USERPROVIDER"); //获取第一个服务器 ServiceInstance inst = instList.get(0); //获取服务提供者服务器ip、端口号 String ip = inst.getHost(); int port = inst.getPort(); //拼接调用地址 String url="http://"+ip+":"+port+"/user"; return url; } @Override public Map getUserMap() { Map map = restTemplate.getForObject(getServerUrl()+"/getall", Map.class); return map; } @Override public void createUser(User user) { restTemplate.postForObject(getServerUrl()+"/save", user,String.class); } @Override public User getUser(Long id) { return restTemplate.getForObject(getServerUrl()+"/get/"+id, User.class); } @Override public void updateUser(Long id, User user) { restTemplate.put(getServerUrl()+"/update/"+id, user); } @Override public void deleteUser(Long id) { restTemplate.delete(getServerUrl()+"/delete/"+id); } }
启动服务,跳转地址 http://localhost:9001/
SpringColud中已经帮咱们集成了一系列负载均衡组件:LoadBalancerClient、Ribbon(缎带)、Feign(装做),简单修改代码便可使用。
新建子模块 userweb02
pom.xml
<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.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>4.2.1</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
配置文件 application.yml
server: port: 9002 spring: thymeleaf: cache: false application: name: userweb02 eureka: client: service-url: defaultZone: http://localhost:10086/eureka/,http://localhost:10087/eureka/
启动类、Bean、UserController、UserService 还和 UserWeb01 项目保持一直,只有UserServiceImpl 有一些变化
// UserServiceImpl.java @Service public class UserServiceImpl implements UserService { //远程服务调用客户端 @Autowired RestTemplate restTemplate; //支持负载均衡的调用客户端 @Autowired LoadBalancerClient loadBalancerClient; /*** * 经过客户端负载均衡器获取生产者服务器基础地址 * @return */ public String getServerUrl() { //经过客户端调用器查找指定服务,只有这里发生了变化。 ServiceInstance inst = loadBalancerClient.choose("USERPROVIDER"); //获取服务提供者服务器ip、端口号 String ip = inst.getHost(); int port = inst.getPort(); //拼接调用地址 String url="http://"+ip+":"+port+"/user"; return url; } ...... // 方法还和之前保持一致 }
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。它是一个基于HTTP和TCP的客户端负载均衡器。
新建子模块 UserWeb03
pom.xml
<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.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>4.2.1</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> </dependencies>
配置文件 application.yml
server: port: 9003 spring: thymeleaf: cache: false application: name: userweb03 #开启Spring Cloud的重试功能 cloud: loadbalancer: retry: enabled: true eureka: client: service-url: defaultZone: http://localhost:10086/eureka/,http://localhost:10087/eureka/ USERPROVIDER: ribbon: # 配置指定服务的负载均衡策略 NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule # Ribbon的链接超时时间 ConnectTimeout: 250 # Ribbon的数据读取超时时间 ReadTimeout: 250 # 是否对全部操做都进行重试 OkToRetryOnAllOperations: true # 切换实例的重试次数 MaxAutoRetriesNextServer: 1 # 对当前实例的重试次数 MaxAutoRetries: 1
启动类修改
@SpringBootApplication @EnableDiscoveryClient public class Userweb03Application { public static void main(String[] args) { SpringApplication.run(Userweb03Application.class, args); } @Bean // 开启 ribbon @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); } }
User、UserController、UserService都和上一个保持一致,只有UserServiceImpl有所不一样
@Service public class UserServiceImpl implements UserService { //远程服务调用客户端 @Autowired RestTemplate restTemplate; //开启Ribbon后,RestTemplate直接使用服务名就能够发起调用 String url="http://USERPROVIDER"; ...... 其它代码一致,取消了getUrl方法 }
5.运行服务 http://localhost:9003/
Feign是一个声明性的web服务客户端,使用Feign建立接口并对其进行注释,就能够经过该接口调用生产者提供的服务。Spring Cloud对Feign进行了加强,使得Feign支持了Spring MVC注解。
建立子模块 UserWeb04
pom.xml
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <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-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>4.2.1</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies>
配置文件 application.yml
server: port: 9004 spring: thymeleaf: cache: false application: name: userweb04 #开启Spring Cloud的重试功能 cloud: loadbalancer: retry: enabled: true eureka: client: service-url: defaultZone: http://localhost:10086/eureka/,http://localhost:10087/eureka/ USERPROVIDER: ribbon: # 配置指定服务的负载均衡策略 NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule # Ribbon的链接超时时间 ConnectTimeout: 250 # Ribbon的数据读取超时时间 ReadTimeout: 250 # 是否对全部操做都进行重试 OkToRetryOnAllOperations: true # 切换实例的重试次数 MaxAutoRetriesNextServer: 1 # 对当前实例的重试次数 MaxAutoRetries: 1 # 设置对应包的日志级别 logging.level.com.offcn.userweb04: debug
编写配置类,定义日志级别,Feign支持4种级别:
@Configuration public class FeignConfig { @Bean public Logger.Level getFeignlogger(){ return Logger.Level.FULL; } }
启动类添加注解 @EnableFeignClients
User、UserController与其它 UserWeb 项目保持一致,可是要删除UserServiceImpl,修改UserService
@FeignClient(value = "USERPROVIDER", configuration = FeignConfig.class) public interface UserService { @GetMapping("/user/getall") public Map<String, Object> getUserMap(); @PostMapping("/user/save") public void createUser(User user); @GetMapping("/user/get/{id}") public User getUser(@RequestParam("id") Long id); @PutMapping("/user/update/{id}") public void updateUser(@RequestParam("id") Long id, @RequestBody User user); @DeleteMapping("/user/delete/{id}") public void deleteUser(@RequestParam("id") Long id); }
运行服务 <>
Hystrix是Netflix开源的一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败。在分布式系统中应用这一模式以后,服务调用方能够本身进行判断某些服务反应慢或者存在大量超时的状况时,可以主动熔断,防止总体系统被拖垮。不一样于电路熔断只能断不能自动重连,Hystrix能够实现弹性容错,当状况好转以后,能够自动重连。
修改子模块 UserWeb03,引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
修改配置文件
# 添加Hystrix熔断超时时间,要求熔断超时 > ribbon 读取超时 hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 700
在启动类添加注解 @EnableCircuitBreaker
修改 UserServiceImpl
@Override @HystrixCommand(fallbackMethod="getUserMapFallbackMethod") public Map getUserMap() { long beginTime = System.currentTimeMillis(); Map map = restTemplate.getForObject(url+"/user/getall", Map.class); long endTime=System.currentTimeMillis(); System.out.println("程序执行时间:"+(endTime-beginTime)); return map; } // 熔断超时,就会执行该方法 public Map<String, Object> getUserMapFallbackMethod() { Map map = new HashMap(); map.put("list", new ArrayList<>()); map.put("ProviderVersion", "获取远程调用失败"); return map; }
修改 UserProvider01,模拟超时状况
@GetMapping("/getall") @ApiOperation(value = "获取所有用户信息", notes = "获取所有用户信息") public Map<String,Object> getUsers() { Map<String,Object> map=new HashMap<>(); List<User> list = userService.getUserList(); map.put("list", list); map.put("ProviderVersion", ProviderVersion); // 模拟超时 try { Thread.sleep(900); } catch (InterruptedException e) { e.printStackTrace(); } return map; }
7.运行服务 http://localhost:9003/
pom 引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
Feign默认也有对Hystrix的集成,只不过,默认状况下是关闭的。咱们须要经过下面的参数来开启,修改UserWeb04 模块的配置文件:
feign: hystrix: enabled: true #设定Hystrix熔断超时时间 hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 700
添加类 UserServiceImpl
@Service public class UserServiceImpl implements UserService { @Override public Map<String, Object> getUserMap() { Map map = new HashMap(); map.put("list", new ArrayList<>()); map.put("ProviderVersion", "获取远程调用失败"); return map; } @Override public void createUser(User user) { System.out.println("建立用户失败:"+user); } @Override public User getUser(Long id) { System.out.println("获取id:"+id+" 的用户失败"); return null; } @Override public void updateUser(Long id, User user) { System.out.println("更新id:"+id+"的用户失败"); } @Override public void deleteUser(Long id) { System.out.println("删除id为:"+id+"的用户失败"); } }
在 UserService中,使用注解@FeignClient声明熔断调用实现类 @FeignClient(value = "USERPROVIDER", configuration = FeignConfig.class, fallback = UserServiceImpl.class)
。熔断超时,就会到该指定类执行对应的方法。
新建子模块 hystrix-dashboard,编辑pom.xml
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</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-netflix-hystrix-dashboard</artifactId> </dependency> </dependencies>
修改配置文件 application.yml
spring: application: name: hystrix-dashboard server: port: 1301
启动类添加注解 @EnableHystrixDashboard
运行服务 http://localhost:1301/hystrix
pom 引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
修改 UserWeb04 启动类,在服务实例的主类中已经使用@EnableCircuitBreaker或@EnableHystrix注解,开启断路器功能。同时增长监控路径访问地址定义/hystrix.stream能够访问。
@SpringBootApplication @EnableDiscoveryClient // 开启假装客户端 @EnableFeignClients // 开启断路器功能 @EnableHystrix public class Userweb04Application { public static void main(String[] args) { SpringApplication.run(Userweb04Application.class, args); } @Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); } @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; } }
启动服务,先执行请求后,而后查看 http://localhost:9004/hystrix.stream
使用Hystrix Dashboard对Hystrix监控数据进行图形化监控。在Hystrix Dashboard的首页输入http://localhost:9004/hystrix.stream,点击“Monitor Stream”按钮。
新建子模块 ConfigServer001,修改pom.xml
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies>
修改配置文件 application.yml
server: port: 7001 spring: application: name: config-server cloud: config: server: git: # 根据本身的状况进行配置 uri: https://github.com/username/repositoryname search-paths: src/main/resources username: username password: password eureka: client: service-url: defaultZone: http://localhost:10086/eureka,http://localhost:10087/eureka
修改UserProvide01的配置文件 application.yml 为 UserProvider01-test.yml 并上传,运行服务执行 http://localhost:7001/UserProvider01-test.yml
将 UserProvider0一、UserProvider0二、UserWeb0一、UserWeb0二、UserWeb0三、UserWeb04 的配置文件 application.yml 修改成 application-dev.yml 并上传到 git 远程仓库,项目自己的配置文件不修改,只是上传git的时候须要更名。
修改以上子模块
pom.xml 引入config
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency>
新建配置文件 bootstrap.yml
spring: application: # 根据本身上传的 yml 文件来定 name: UserProvider01 cloud: config: discovery: enabled: true # 根据 configserver001 的 application.name 来定。 service-id: config-server # 根据本身上传的 yml 文件来定 profile: dev label: master eureka: client: service-url: defaultZone: http://localhost:10086/eureka,http://localhost:10087/eureka
将原有的 application.yml 清空,加上新的内容,能够在配置文件中的内容有改动的时候,不用重启服务,动态刷新,须要在相应的调用类上加新的注解 @RefreshScope
。
management: endpoints: web: exposure: include: refresh,health,info
运行服务,而后启动任意一个客户端,查看运行状况
新建子模块 ZuulGateWay,修改 pom.xml
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> </dependencies>
修改配置文件:application.yml
spring: application: name: zull-gateway server: port: 80 # 经过 url 直接映射 #zuul: # routes: # userprovider001: # # userprovider001 部分为路由的名字,能够任意定义,可是一组映射关系的path和url要相同 # path: /userprovider001/** # url: http://localhost:8001/ # userprovider002: # path: /userprovider002/** # url: http://localhost:8002/ # 经过 serviceId的映射方式支持了断路器,对于服务故障的状况下,能够有效的防止故障蔓延到服务网关上而影响整个系统的对外服务。 eureka: client: service-url: defaultZone: http://localhost:10086/eureka,http://localhost:10087/eureka zuul: routes: userprovider: path: /service/** service-id: USERPROVIDER # 就是将web中的配置 到zuul中 这样多个web都用熔断 仅须要写一次 而没必要要每一个web 都配置。 retryable: true #打开重试 ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule ConnectionTimeOut: 250 ReadTimeout: 1000 OkToRetryOnAllOperations: true MaxAutoRetriesNextServer: 1 MaxAutoRetries: 1 #设定Hystrix熔断超时时间 hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 2000
启动类
@EnableZuulProxy // 包含了 @SpringBootApplication、@EnableDiscoveryClient、@EnableCircuitBreaker @SpringCloudApplication public class ZuulgatewayApplication { public static void main(String[] args) { SpringApplication.run(ZuulgatewayApplication.class, args); } }
Zuul服务网关过滤器
public class AccessFilter extends ZuulFilter { /** * 四种不一样生命周期 * pre:能够在请求被路由以前调用 * routing:在路由请求时候被调用 * post:在routing和error过滤器以后被调用 * error:处理请求时发生错误时被调用 * @return */ @Override public String filterType() { return "pre"; } /** * 过滤器的执行顺序 * @return */ @Override public int filterOrder() { return 0; } /** * 过滤器是否要执行 * @return */ @Override public boolean shouldFilter() { return true; } @Override public Object run() throws ZuulException { RequestContext ctx= RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); String token = request.getParameter("accesstoken"); if(token == null) { // 过滤该请求,不对其进行路由 ctx.setSendZuulResponse(false); // 返回的错误码。也能够经过ctx.setResponseBody(body)对返回 ctx.setResponseStatusCode(401); return null; } return null; } }
在启动类中实例化该过滤器
@Bean public AccessFilter accessFilter() { return new AccessFilter(); }
启动服务,进行测试