Rumah > Java > javaTutorial > teks badan

Had semasa antara muka, semua operasi hebat ada di sini!

Lepaskan: 2023-07-26 14:22:33
ke hadapan
1139 orang telah melayarinya

Mengapa semasa mengehadkan

Apabila mereka bentuk sistem, kita akan mempunyai anggaran kapasiti sistem Jika ia melebihi ambang TPS/QPS yang sistem boleh tahan lama, sistem mungkin terharu, akhirnya menyebabkan keseluruhan perkhidmatan menjadi Tidak tersedia. Untuk mengelakkan situasi ini, kita perlu mengehadkan aliran permintaan antara muka.

Jadi, kami boleh melindungi sistem atau mengelakkan pembaziran sumber yang tidak perlu dengan mengehadkan kadar permintaan akses serentak atau bilangan permintaan dalam tetingkap masa Setelah had kadar dicapai, kami boleh menafikan perkhidmatan, beratur atau menunggu.

Latar belakang mengehadkan semasa

Sistem ini mempunyai antara muka untuk mendapatkan kod pengesahan SMS telefon mudah alih Kerana ia adalah antara muka terbuka, untuk mengelakkan pengguna daripada terus menghantar permintaan untuk mendapatkan kod pengesahan dan menghalang percubaan berniat jahat untuk meleret. antara muka, kami menggunakan yang terkini Kaedah kaunter mudah digunakan untuk mengehadkan aliran semasa, mengehadkan setiap IP kepada hanya satu permintaan seminit, dan kemudian had tetingkap masa nombor telefon mudah alih satu sama lain dinilai melalui logik perniagaan. Secara amnya, sesetengah antara muka mempunyai bilangan lawatan yang agak besar dan mungkin mengatasi sistem, jadi sekatan trafik perlu ditambah! Seperti: jualan kilat, dll...

Kaedah pelaksanaan

1. Memperkenalkan tanggungan

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Salin selepas log masuk

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RateLimiter {
    /**
     * 限流key
     */
     String key() default Constants.RATE_LIMIT_KEY;

    /**
     * 限流时间,单位秒
     */
     int time() default 60;

    /**
     * 限流次数
     */
    int count() default 100;

    /**
     * 限流类型
     */
    LimitType limitType() default LimitType.DEFAULT;

    /**
     * 限流后返回的文字
     */
    String limitMsg() default "访问过于频繁,请稍候再试";
}
Salin selepas log masuk

3. Aliran Terhad bahagian
@Aspect
@Component
public class RateLimiterAspect {

    private final static Logger log = LoggerFactory.getLogger(RateLimiterAspect.class);

    @Autowired
    private RedisUtils redisUtils;

    @Before("@annotation(rateLimiter)")
    public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable {
        int time = rateLimiter.time();
        int count = rateLimiter.count();
        long total = 1L;

        String combineKey = getCombineKey(rateLimiter, point);
        try
        {
            if(redisUtils.hasKey(combineKey)){
                total = redisUtils.incr(combineKey,1);  //请求进来,对应的key加1
                if(total > count)
                    throw new ServiceRuntimeException(rateLimiter.limitMsg());
            }else{
                redisUtils.set(combineKey,1,time);  //初始化key
            }
        }
        catch (ServiceRuntimeException e)
        {
            throw e;
        }
        catch (Exception e)
        {
            throw new ServiceRuntimeException("网络繁忙,请稍候再试");
        }
    }

    /**
     * 获取限流key
     * @param rateLimiter
     * @param point
     * @return
     */
    public String getCombineKey(RateLimiter rateLimiter, JoinPoint point) {
        StringBuffer stringBuffer = new StringBuffer(rateLimiter.key());
        if (rateLimiter.limitType() == LimitType.IP)
        {
            stringBuffer.append(IpUtils.getIpAddr(ServletUtils.getRequest())).append("-");
        }
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        Class<?> targetClass = method.getDeclaringClass();
        stringBuffer.append(targetClass.getName()).append("-").append(method.getName());
        return stringBuffer.toString();
    }

}
Salin selepas log masuk

4 Tulis antara muka yang mudah untuk menguji
@RestController
public class TestController {

    @RateLimiter(time = 60, count = 1, limitType = LimitType.IP, limitMsg = "一分钟内只能请求一次,请稍后重试")
    @GetMapping("/hello")
    public ResultMsg hello() {
        return ResultMsg.success("Hello World!");
    }
}
Salin selepas log masuk

pengecualian global.

6 . Ujian antara muka🎜

1) Kali pertama anda menghantarnya, hasilnya akan dikembalikan seperti biasa

Had semasa antara muka, semua operasi hebat ada di sini!

2) Kali kedua anda menghantarnya dalam masa satu minit, anda akan mendapat ralat dan gesaan had semasa

Had semasa antara muka, semua operasi hebat ada di sini!

The di atas adalah AOP + Redis penyelesaian untuk melaksanakan had semasa antara muka, anda Adakah anda telah kehilangan pengajian anda?

Terdapat kaedah pengehad semasa yang lain, seperti kaedah pengehad arus tingkap gelongsor (lebih ketat daripada kaunter), baldi token, dll... Rakan-rakan yang berminat boleh mempelajarinya.


Atas ialah kandungan terperinci Had semasa antara muka, semua operasi hebat ada di sini!. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:Java学习指南
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan