Nginx负载均衡
http {
...
upstream tomcats {
server 192.168.0.100:8080;
server 192.168.0.101:8080;
server 192.168.0.102:8080;
}
server {
listen 80;
location / {
proxy_pass http://tomcats;
}
}
...
}
在上游配置代理服务器组,并定位为集proxy_pass上游组名。当请求到来时,Nginx会轮询服务器在指定的上游过程。上游服务器也可以增加参数。最常用的权重是权重,指定服务器的权重,默认值为1。哪一台服务器性能好,它的重量有点小,一个能干的人总是很忙。示例如下
upstream tomcats {
server 192.168.0.100:8080 weight=2; #2/6次
server 192.168.0.101:8080 weight=3; #3/6次
server 192.168.0.102:8080 weight=1; #1/6次
}
redis 分布式锁
分布式锁的实现方式有三种:数据库,缓存和zookeeper。原理简单来说就是用一个key做锁,set这个key,成功就是获得了锁。解锁时删除这个key,并判断value是不是当时设置的值,相等才删除,防止别的进程强制删除当前key来获取锁。代码如下
public class RedisTool {
private static final String LOCK_SUCCESS="OK";
private static final String SET_IF_NOT_EXIST="NX";
// 延时的时间单位,PX是毫秒,EX是秒
private static final String SET_WITH_EXPIRE_TIME="PX";
private static final Long RELEASE_SUCCESS=1L;
/**
* 尝试获取分布式锁
* @param jedis Redis客户端
* @param lockKey 锁
* @param requestId 请求标识
* @param expireTime 超期时间
* @return 是否获取成功
*/
public static boolean tryGetDistributedLock(Jedis jedis,String lockKey,String requestId,int expireTime) {
String result = jedis.set(lockKey,requestId,SET_IF_NOT_EXIST,SET_WITH_EXPIRE_TIME,expireTime);
if (LOCK_SUCCESS.equals(result)){
return true;
}
return false;
}
/**
* 释放分布式锁
* @param jedis Redis客户端
* @param lockKey 锁
* @param requestId 请求标识
* @return 是否成功释放
*/
public static boolean releaseDistributedLock(Jedis jedis,String lockKey, String requestId) {
String script = "if redis.call('get',KEYS[1]) == ARGV[1] " + "then return redis.call('del', KEYS[1]) " + "else return 0 end;"
Object result = jedis.eval(script, Collections.singletonList(lockKey),Collection.singletonList(requestId));
if (RELEASE_SUCCESS.equals(result)) {
return true;
}
return false;
}
}
跟进问题
分布式锁只能解决多线程不能同时访问同一个资源的问题。如果多个线程访问不同的资源,例如,服务器只能同时处理50个请求,但有500个请求。我们如何处理,我想是队列MQ。