1. eureka服務的建立配置: 建立的時候選擇建立spring-boot專案然後選擇eureka依賴eureka-server,然後點選完成;
application.properties檔案的配置:
#服務的名稱spring.application.name=spring-cloud-eureka-server #配置eureka的預設埠server.port=8761#指定註冊到eurekaserver服務地址8762是eureka的副本服務地址埠;主要為了實現高可用。防止eureka註冊中心掛掉後服務不可用#eureka.client.service-url.defaultZone=http://localhost:8762/eureka eureka.client.service-url.defaultZone=http://localhost:8761/eureka #透過主機名進行對映#eureka.instance.hostname=eureka1 #是否向服務註冊中心註冊自己(如果僅作為呼叫者,不提供服務,可以為false)eureka.client.register-with-eureka=false#是否去eurekaserver獲取服務地址資訊eureka.client.fetch-registry=false#將IP註冊到eureka中,如果為false預設註冊主機名#eureka.instance.prefer-ip-address=true
2.服務提供者搭建:基於openfeign的多模組的搭建:package org.example; import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping; /** * api介面的定義,服務端實現介面共客戶端呼叫 */public interface IUserService { @PostMapping("/user") String insertUser(User user); @GetMapping("/user") String queryUser();} package org.example; import org.springframework.cloud.openfeign.FeignClient; /** openfeign 介面的定義 * @FeignClient("spring-cloud-user-provider") 解析服務名,進行通訊連線 */@FeignClient("spring-cloud-user-provider")public interface IUserServiceFeign extends IUserService{ }package org.example; public class User { private String name; public void setName(String name) { this.name = name; } public String getName() { return name; } @Override public String toString() { return "User{" + "name='" + name + '\'' + '}'; }} 9.建立一個子模組springboot專案作為服務方user-provider;建立方式:依賴:
application.properties配置檔案:
spring.application.name=spring-cloud-user-provider server.port=8080 eureka.client.service-url.defaultZone=http://localhost:8761/eureka
3.gateway部分的搭建:選擇gateway一個依賴就可以:
application.yml配置:
# gateway 閘道器路由的配置應用spring: application: name: spring-cloud-gateway cloud: gateway: routes: #多路由的配置 - id: request_ratelimiter_route #閘道器對映到的路徑 uri: http://localhost:8080/ #斷言的設定,一種路由匹配規則,對請求的路徑進行判斷 predicates: #對映路徑 -> http://localhost:8088/gateway/user - Path=/ratelimiter/** # 路徑引數的對映 http://localhost:8088/gateway/user?name=zhou - Query=name,zhou - Method=GET filters: # 路徑過濾,去掉路徑字首引數個數 gateway:http://localhost:8088/gateway/test -> http://localhost:8088/test - StripPrefix=1 - name: RequestRateLimiter #過濾器名字 args: #過濾的引數設定 keyResolver: '#{@ipAddressKeyResolver}' #配置引入定義的限流的keyResolver redis-rate-limiter.replenishRate: 1 # 每秒生成的令牌桶的個數 redis-rate-limiter.burstCapacity: 2 #令牌桶的容量 #重試機制的過濾配置; id:路由的名稱,多個路由區別名 - id: retry_route predicates: - Path=/retry/** uri: http://localhost:8080/ filters: - StripPrefix=1 - name: Retry args: retries: 3 #重試的次數 status: 503 #當服務端返回的狀態碼是503的時候才會觸發重試 #自定義過濾器 - id: define_route predicates: - Path=/define/** uri: http://localhost:8080/ filters: - StripPrefix=1 - MyDefine=Zhou_Guanjun # redis 主機地址的配置 redis: host: 192.168.1.7 port: 6379 timeout: 5000server: port: 8088
package com.self.springcloud.springcloudgateways; import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;import org.springframework.stereotype.Component;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono; /** 定義一個IP地址的方式的限流key * 獲取遠端的IP地址 */@Componentpublic class IpAddressKeyResolver implements KeyResolver{ @Override public Mono<String> resolve(ServerWebExchange exchange) { return Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()); }}
注意:連線Redis限流的時候,需要注意Redis的配置檔案redis.conf, protect-mode no(不開啟保護模式),bind127.0.0.1需要注掉,否則不允許外部 不連線,timeout 5000(連線時間預設是0,不能設定0,否則連不上),最後關閉防火牆。測試Redis的連線:package com.self.springcloud.springcloudgateways; import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;import org.springframework.data.redis.serializer.StringRedisSerializer; /** * Redis配置類 */@Configurationpublic class RedisConfig { /** * JSON序列化方式 * @param redisConnectionFactory RedisConnectionFactory * @return RedisTemplate */ @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; } }
package com.self.springcloud.springcloudgateways; public interface IRedisService { void test();}
package com.self.springcloud.springcloudgateways; public class Person { private String id; private String name; public String getName() { return name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}'; }}
package com.self.springcloud.springcloudgateways; import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.stereotype.Service; @Servicepublic class RedisServiceImpl implements IRedisService { Logger logger= LoggerFactory.getLogger(RedisServiceImpl.class); @Autowired private StringRedisTemplate stringRedisTemplate; @Autowired private RedisTemplate<String, Object> redisTemplate; @Override public void test() { stringRedisTemplate.opsForValue().set("key", "value"); String string = stringRedisTemplate.opsForValue().get("key"); Person person = new Person(); person.setId("123"); person.setName("test"); redisTemplate.opsForValue().set("key-0", person); Person person1 = (Person) redisTemplate.opsForValue().get("key-0"); logger.info("person de value:string="+string+"----"+String.valueOf(person1)); } }
package com.self.springcloud.springcloudgateways; import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;import org.springframework.web.bind.annotation.RestController; @RunWith(SpringRunner.class)@SpringBootTestpublic class TestController { @Autowired RedisServiceImpl redisService; @Test public void test(){ redisService.test(); } }
測試連線成功,啟動服務不會報錯,控制檯會輸出新增的key的值:"person de value:string="+string+"----" value 123 testpackage com.self.springcloud.springcloudgateways; import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.cloud.gateway.filter.GatewayFilter;import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;import org.springframework.stereotype.Component;import reactor.core.publisher.Mono; import java.util.Arrays;import java.util.List;import java.util.concurrent.Exchanger; /** 自定義過濾器,當系統給定的過濾器不能滿足自己的需求的時候,實現的時候名字必須是---GatewayFilterFactory結尾的形式 * 就需要自定義的過濾方式,達到一定的要求 * 這個是針對單個路由的,需要在配置檔案中進行路由配置 * 全域性過濾器 globalFilter * */@Componentpublic class MyDefineGatewayFilterFactory extends AbstractGatewayFilterFactory<MyDefineGatewayFilterFactory.Config>{ Logger logger= LoggerFactory.getLogger(MyDefineGatewayFilterFactory.class); public MyDefineGatewayFilterFactory(){ super(Config.class); } /** * 配置字首名的使用 */ public static final String NAME_KEY="name"; @Override public List<String> shortcutFieldOrder() { return Arrays.asList(NAME_KEY); } /** * 過濾的核心邏輯方法 * @param config * @return */ @Override public GatewayFilter apply(Config config) { return ((exchange,chain)->{ //前置的處理 logger.info("[Pred] filter request, name :" +config.getName()); //後置的處理 return chain.filter(exchange).then(Mono.fromRunnable(()->{ String code=exchange.getResponse().getStatusCode().toString(); logger.info("[post] response Filter "+code); })); }); } public static class Config{ private String name; public void setName(String name) { this.name = name; } public String getName() { return name; } }}
package com.self.springcloud.springcloudgateways; import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.cloud.gateway.filter.GatewayFilterChain;import org.springframework.cloud.gateway.filter.GlobalFilter;import org.springframework.core.Ordered;import org.springframework.stereotype.Component;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono; import javax.sound.sampled.Line; /** * 全域性過濾器路由的配置,針對整個工程而言,可以用於配置日誌管理,和鑑權; * 不需要在配置檔案配置,直接寫完這個類的邏輯就可以了 * */@Componentpublic class MyGlobalFilter implements GlobalFilter, Ordered { Logger logger= LoggerFactory.getLogger(MyGlobalFilter.class); /** * 主要的邏輯程式碼部分 * @param exchange * @param chain * @return */ @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { logger.info("[pred] 前置處理邏輯:"); return chain.filter(exchange).then(Mono.fromRunnable(()->{ logger.info("[post] 後置處理邏輯:"); })); } /** * 表示當前過濾連所處的順序,值越大優先順序越小,預設是 0 ; * @return */ @Override public int getOrder() { return 0; }}
本文連結:
https://blog.csdn.net/weixin_43797976/article/details/113888512