Spring Cloud Gateway 入门实战
发布日期:2021-04-30 21:04:20 浏览次数:116 分类:精选文章

本文共 6554 字,大约阅读时间需要 21 分钟。

微服务系统中熔断降级与限流实践指南

1. 搭建基础的Spring Boot工程

我们从一个标准的Spring Boot项目开始,通过Maven pom.xml文件来管理依赖关系。需要注意的是,版本号要与Spring Cloud组件保持一致。

4.0.0
org.springframework.boot
spring-boot-starter-parent
2.2.5.RELEASE
com.example
demo
0.0.1-SNAPSHOT
demo
Demo project for gateway
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
2.2.1.RELEASE
org.springframework.cloud
spring-cloud-starter-gateway
2.2.3.RELEASE
org.springframework.boot
spring-boot-starter-data-redis-reactive
2.2.5.RELEASE
org.springframework.cloud
spring-cloud-starter-netflix-hystrix
2.2.3.RELEASE
org.springframework.boot
spring-boot-maven-plugin

2. 开启Nacos注解

在主类中启用Nacos发现客户端注解。

@SpringBootApplication@EnableDiscoveryClientpublic class DemoApplication {    public static void main(String[] args) {        SpringApplication.run(DemoApplication.class, args);    }}

3. 新建HystrixController

用于处理服务异常或超时时的降级逻辑。

package com.example.demo.controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;import java.util.Map;@RestController@RequestMapping("/hystrix")public class HystrixController {    @RequestMapping("/defaultfallback")    public Map
defaultfallback() { System.out.println("降级操作..."); Map
map = new HashMap<>(); map.put("code", "500"); map.put("message", "服务异常"); return map; }}

4. 配置bootstrap.yml

配置Nacos地址和命名空间(具体配置请参考前文)。

spring:    application:        name: cloud-gateway    cloud:        nacos:            discovery:                server-addr: 192.168.1.54:8848                namespace: MaoJiaFenglogging:    level:        com:            alibaba:                nacos:                    client:                        error

5. 配置application.yml

配置网关路由、限流和熔断降级参数。

server:    port: 9527spring:    redis:        host: 192.168.1.52        port: 6379        password: KCl9HfqbVnhQ5c3n        database: 15cloud:    gateway:        routes:            - id: springboot-api                uri: lb://springboot-api                predicates:                    - Path=/test/**                filters:                    - name: Hystrix                        args:                            name: default                            fallbackUri: 'forward:/hystrix'                    - name: RequestRateLimiter                        args:                            name: default                            key-resolver: "#{@remoteAddrKeyResolver}"                            redis-rate-limiter.replenishRate: 1                            redis-rate-limiter.burstCapacity: 5hystrix:    command:        default:            execution:                isolation:                    strategy: SEMAPHORE                thread:                    timeoutInMilliseconds: 3000                shareSecurityContext: true

6. 验证熔断降级

启动网关后,通过访问服务端口8088的接口测试:

  • /hello 接口返回正常。
  • /timeout 接口由于5秒延时返回服务异常,网关配置的Hystrix降级逻辑会自动触发,返回 {“code”:“500”,“message”:“服务异常”}

7. 配置限流

新增RateLimiterConfig类。

package com.example.demo.config;import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import reactor.core.publisher.Mono;@Configurationpublic class RateLimiterConfig {    @Bean    public KeyResolver remoteAddrKeyResolver() {        return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());    }}

通过编写并发测试代码,验证限流配置:

package com.example.demo.test;import com.example.demo.util.HttpClientOp;import java.util.concurrent.CountDownLatch;public class LatchTest {    public static void main(String[] args) throws InterruptedException {        Runnable taskTemp = new Runnable() {            private int iCounter;            @Override            public void run() {                for (int i = 0; i < 10; i++) {                    System.out.println(HttpClientOp.doGet("http://localhost:9527/test/hello"));                    iCounter++;                    System.out.println(System.nanoTime() + " [" + Thread.currentThread().getName() + "] iCounter = " + iCounter);                    try {                        Thread.sleep(100);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        };        LatchTest latchTest = new LatchTest();        latchTest.startTaskAllInOnce(5, taskTemp);    }    public long startTaskAllInOnce(int threadNums, final Runnable task) throws InterruptedException {        final CountDownLatch startGate = new CountDownLatch(1);        final CountDownLatch endGate = new CountDownLatch(threadNums);        for (int i = 0; i < threadNums; i++) {            Thread t = new Thread() {                public void run() {                    try {                        startGate.await();                        try {                            task.run();                        } finally {                            endGate.countDown();                        }                    } catch (InterruptedException ie) {                        ie.printStackTrace();                    }                }            };            t.start();        }        long startTime = System.nanoTime();        System.out.println(startTime + " [" + Thread.currentThread() + "] All thread is ready, concurrent going...");        startGate.countDown();        endGate.await();        long endTime = System.nanoTime();        System.out.println(endTime + " [" + Thread.currentThread() + "] All thread is completed.");        return endTime - startTime;    }}

通过以上配置,可以验证每秒的最大访问次数和令牌桶容量限制效果。

上一篇:JVM学习笔记002:垃圾回收
下一篇:输入参数

发表评论

最新留言

逛到本站,mark一下
[***.202.152.39]2026年06月10日 07时11分34秒