先抛出一个问题,如何解决互联网项目中的高并发问题?
1.网络层
2.服务器层面,常用的有nginx分流,负载均衡,负载权重。这些就是为了减轻单台服务器的压力。
3.业务划分
这才是高并发解决方案的重点,系统应该被细粒度地分割成多个模块,如天猫的购物车系统、结算系统等,在具体划分出来的系统上做负载均衡等。
4.代码层面的限流策略。访问太多的话就拒绝。
5.缓存层面限流,或者说是session层面的限流;即一个用户访问一个url最多多少次,缓存可以用redis完成,redis中有实现这样的功能。
代码层面的限流策略
Semaphore sema = new Semaphore(5);//这里的5就表示最多接受5个线程。
sema.aquire();//获取授权
代码块;
sema.release();//释放
1 import java.util.concurrent.ExecutorService; 2 import java.util.concurrent.Executors; 3 import java.util.concurrent.Semaphore; 4 5 public class UseSemaphore { 6 7 public static void main(String[] args) { 8 // 线程池 9 ExecutorService exec = Executors.newCachedThreadPool(); 10 // 只能5个线程同时访问 11 final Semaphore semp = new Semaphore(5); 12 // 模拟20个客户端访问 13 for (int index = 0; index < 20; index++) { 14 final int NO = index; 15 Runnable run = new Runnable() { 16 public void run() { 17 try { 18 // 获取许可 19 semp.acquire(); 20 System.out.println("Accessing: " + NO); 21 //模拟实际业务逻辑 22 Thread.sleep((long) (Math.random() * 10000)); 23 // 访问完后,释放 24 semp.release(); 25 } catch (InterruptedException e) { 26 } 27 } 28 }; 29 exec.execute(run); 30 } 31 32 try { 33 Thread.sleep(10); 34 } catch (InterruptedException e) { 35 e.printStackTrace(); 36 } 37 38 //System.out.println(semp.getQueueLength()); 39 40 41 42 // 退出线程池 43 exec.shutdown(); 44 } 45 46 }
AQS相关知识可以看:https://javadoop.com/2017/07/20/AbstractQueuedSynchronizer-2/