目录
pom.xml
<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-server01
pom.xml
<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.yml
#内置的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
为启动类添加注解
@springbootapplication // 开启 eurekaserver @enableeurekaserver public class eurekaserver01application { public static void main(string[] args) { springapplication.run(eurekaserver01application.class, args); }}
和 eureka-server01 一样,新建一个子模块eureka-server02,只改一下配置文件 application.yml,其它保持一致。
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://www.lhsxpumps.com/_localhost:10086/eureka
运行两个服务器 和 都可以
新建子模块 userprovider01
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); } }
启动服务,跳转地址
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.运行服务
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.运行服务
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
运行服务
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; } }
启动服务,先执行请求后,然后查看
使用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 并上传,运行服务执行
将 userprovider01、userprovider02、userweb01、userweb02、userweb03、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(); }
启动服务,进行测试
如对本文有疑问, 点击进行留言回复!!
秋招无助?推荐这个Github上的Java进阶面试解析Note详细清晰,这你不Satr?
洛谷 P4316 绿豆蛙的归宿(算法竞赛进阶指南,概率数学期望, 拓扑排序)
Educational DP Contest / DP まとめコンテスト部分题解
网友评论