今天没事情问朋友 他们商城多并发问题用的是分布式锁吗,但是人家和我说了用了谷歌的RateLimiter。毕竟他们都开始用了,说明能用的,开始偷学了。
使用场景:
1)业务用户量不断飙升
2)各种促销 抢购等高并发
3)网路爬虫
4)恶意刷单
RateLimiter使用的是一种叫令牌桶的流控算法,会按照一定的频率往桶里扔令牌,线程拿到令牌才能执行,比如你希望自己的应用程序QPS不要超过1000,那么RateLimiter设置1000的速率,就会每秒往桶里扔1000个令牌。
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
private static final SimpleDateFormat FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:S");
private static final int THREAD_COUNT = 25;
@Test
public void testRateLimiter1() throws InterruptedException {
RateLimiter rateLimiter = RateLimiter.create(5);
Thread[] ts = new Thread[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; i++) {
ts[i] = new Thread(new RateLimiterThread(rateLimiter), "RateLimiterThread-" + i);
}
for (int i = 0; i < THREAD_COUNT; i++) {
Thread.sleep(50);
ts[i].start();
}
for (;;);
}
public class RateLimiterThread implements Runnable {
private RateLimiter rateLimiter;
public RateLimiterThread(RateLimiter rateLimiter) {
this.rateLimiter = rateLimiter;
}
@Override
public void run() {
if (rateLimiter.tryAcquire()){
System.out.println(Thread.currentThread().getName() + "获取到了令牌,时间 = " + FORMATTER.format(new Date()));
}else {
System.out.println(Thread.currentThread().getName() + "没有令牌" + FORMATTER.format(new Date()));
}
}
}
在这边设置了一个线程睡了50毫秒
一秒创建5个令牌,相当于一个线程要200ms可以拿到一个令牌去执行东西。
一共25个线程,也差不多是200ms有一个线程能拿到一个令牌。
顺便问了前端的大佬,原来前端也要做限流的,节流防抖……
补一下今天的小问题。
有个表情包评论的,但是移动端自带的em表情是三个字节,但是utf-8正常是两个字节的。最后百度了,在数据库做了改动。将该字段字符集转为utf8mb4,排序规则是utf8mb4_unicode_ci。
这样子就可以了!