diff --git a/javamemories-gateway/pom.xml b/javamemories-gateway/pom.xml new file mode 100644 index 0000000..725d67c --- /dev/null +++ b/javamemories-gateway/pom.xml @@ -0,0 +1,47 @@ + + 4.0.0 + + cn.mayiming + javamemories-parent + 1.0-SNAPSHOT + + + javamemories-gateway + jar + + javamemories-gateway + http://maven.apache.org + + + UTF-8 + + + + + + org.springframework.cloud + spring-cloud-starter-gateway + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + org.springframework.cloud + spring-cloud-starter-loadbalancer + + + + org.springframework.boot + spring-boot-starter-data-redis-reactive + + + + redis.clients + jedis + + + diff --git a/javamemories-gateway/src/main/java/cn/mayiming/App.java b/javamemories-gateway/src/main/java/cn/mayiming/App.java new file mode 100644 index 0000000..bd10567 --- /dev/null +++ b/javamemories-gateway/src/main/java/cn/mayiming/App.java @@ -0,0 +1,17 @@ +package cn.mayiming; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Hello world! + * + */ +@SpringBootApplication +public class App +{ + public static void main( String[] args ) + { + SpringApplication.run(App.class, args); + } +} diff --git a/javamemories-gateway/src/main/java/cn/mayiming/Config/GatewayRateLimitConfig.java b/javamemories-gateway/src/main/java/cn/mayiming/Config/GatewayRateLimitConfig.java new file mode 100644 index 0000000..9ff6ca3 --- /dev/null +++ b/javamemories-gateway/src/main/java/cn/mayiming/Config/GatewayRateLimitConfig.java @@ -0,0 +1,49 @@ +package cn.mayiming.Config; + +import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +/** + * 网关限流配置类 + * 定义基于IP的限流解析器 + */ +@Configuration +public class GatewayRateLimitConfig { + + /** + * IP限流解析器 + * 作用:从请求中提取客户端IP作为限流的key + */ + @Bean + public KeyResolver ipKeyResolver() { + return exchange -> { + // 获取客户端IP地址 + String ip = getClientIp(exchange); + return Mono.just(ip); + }; + } + + /** + * 处理X-Forwarded-For头,获取真实客户端IP(适配反向代理场景) + */ + private String getClientIp(ServerWebExchange exchange) { + String ip = exchange.getRequest().getHeaders().getFirst("X-Forwarded-For"); + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = exchange.getRequest().getHeaders().getFirst("Proxy-Client-IP"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = exchange.getRequest().getHeaders().getFirst("WL-Proxy-Client-IP"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress(); + } + // 处理多个IP的情况(X-Forwarded-For可能包含多个IP,取第一个) + if (ip != null && ip.contains(",")) { + ip = ip.split(",")[0].trim(); + } + return ip; + } +} \ No newline at end of file diff --git a/javamemories-gateway/src/main/resources/application.yml b/javamemories-gateway/src/main/resources/application.yml new file mode 100644 index 0000000..4f03ffe --- /dev/null +++ b/javamemories-gateway/src/main/resources/application.yml @@ -0,0 +1,60 @@ +server: + port: 8080 + +spring: + application: + name: gateway-service + cloud: + gateway: + discovery: + locator: + enabled: true # 自动从 nacos 发现服务 + routes: + # 路由1:user-service + - id: user-service + uri: lb://user-service # lb = 负载均衡 + predicates: + - Path=/user/** + filters: + - RewritePath=/user/(?.*), /${segment} + # 全局限流配置 + - name: RequestRateLimiter + args: + # 令牌桶填充速率:每秒生成 1 个令牌(即 10 秒 10 个) + redis-rate-limiter.replenishRate: 1 + # 令牌桶最大容量:最多存 10 个令牌(允许突发 10 次请求) + redis-rate-limiter.burstCapacity: 10 + # 按 IP 限流(默认) + key-resolver: "#{@ipKeyResolver}" + + # 路由2:order-service + - id: order-service + uri: lb://order-service + predicates: + - Path=/order/** + filters: + - RewritePath=/user/(?.*), /${segment} + # 全局限流配置 + - name: RequestRateLimiter + args: + # 令牌桶填充速率:每秒生成 1 个令牌(即 10 秒 10 个) + redis-rate-limiter.replenishRate: 1 + # 令牌桶最大容量:最多存 10 个令牌(允许突发 10 次请求) + redis-rate-limiter.burstCapacity: 10 + # 按 IP 限流(默认) + key-resolver: "#{@ipKeyResolver}" + + # Nacos 注册 + nacos: + discovery: + server-addr: localhost:8848 # Nacos 服务地址(默认端口 8848) + namespace: public # 命名空间(默认 public,自定义需先在 Nacos 控制台创建) + group: DEFAULT_GROUP # 分组(默认 DEFAULT_GROUP) + service: gateway-service + data: + redis: + host: localhost + port: 6379 + password: '' + database: 0 + timeout: 2000ms \ No newline at end of file diff --git a/javamemories-gateway/src/test/java/cn/mayiming/AppTest.java b/javamemories-gateway/src/test/java/cn/mayiming/AppTest.java new file mode 100644 index 0000000..2244532 --- /dev/null +++ b/javamemories-gateway/src/test/java/cn/mayiming/AppTest.java @@ -0,0 +1,38 @@ +package cn.mayiming; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/pom.xml b/pom.xml index 3d12727..03195fd 100644 --- a/pom.xml +++ b/pom.xml @@ -91,6 +91,8 @@ javamemories-common user-service order-service + javamemories-gateway + request-test diff --git a/request-test/pom.xml b/request-test/pom.xml new file mode 100644 index 0000000..8b2162a --- /dev/null +++ b/request-test/pom.xml @@ -0,0 +1,28 @@ + + 4.0.0 + + cn.mayiming + javamemories-parent + 1.0-SNAPSHOT + + + request-test + jar + + request-test + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + 3.8.1 + test + + + diff --git a/request-test/src/main/java/cn/mayiming/App.java b/request-test/src/main/java/cn/mayiming/App.java new file mode 100644 index 0000000..93abe3a --- /dev/null +++ b/request-test/src/main/java/cn/mayiming/App.java @@ -0,0 +1,13 @@ +package cn.mayiming; + +/** + * Hello world! + * + */ +public class App +{ + public static void main( String[] args ) + { + System.out.println( "Hello World!" ); + } +} diff --git a/request-test/src/test/java/cn/mayiming/AppTest.java b/request-test/src/test/java/cn/mayiming/AppTest.java new file mode 100644 index 0000000..2244532 --- /dev/null +++ b/request-test/src/test/java/cn/mayiming/AppTest.java @@ -0,0 +1,38 @@ +package cn.mayiming; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +}