目錄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(); }
啓動服務,進行測試