0022-0026 教程学习笔记
0022 Nginx与高可用
1.什么是分布式?
不同模块,部署在不同机器上,解决的是高并发的问题
2.什么是集群?
将一个项目部署在多个节点上
3.什么是SpringCloud? 是一个rpc微服务框架,提供注册服务,发现服务,断路器,网关,自动配置
0024 zookeeper
1.Zookeeper是分布式协调工具,可以做协调,统一配置,分布式共享锁,统一名称服务
2.Zookeeper集群:一个leader,多个follower组成的集群
3.zookeeper存储结构: 以节点(node)方式存储,
4.zookeeper服务领域:主从协调,服务器节点动态上下线,统一配置管理,分布式共享锁,统一命名服务

5.分布式锁解决思路
分布式锁使用zk,在zk上创建一个临时节点(有效期) ,使用临时节点作为锁,因为节点不允许重复。
如果能创建节点成功,生成订单号,如果创建节点失败,等待。临时节点zk关闭,释放锁,其他节点就可以重新生成订单号。
为什么不用数据库? 因为数据库会操作Io,并且容易产生死锁
redis:redis自定义失败
#####生成订单号######
import java.text.SimpleDateFormat;
import java.util.Date;
//生成订单号
public class OrderNumGenerator {
private static int count = 0;
//生成订单号
public String getOrderNumber() {
SimpleDateFormat smt = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
return smt.format(new Date()) + "-" + ++count;
}
}
#####订单业务逻辑######
public class OrderService implements Runnable {
private OrderNumGenerator orderNumGenerator = new OrderNumGenerator();
private static Object oj = new Object();
private Lock lock = new ZookeeperDistrbuteLock();
public void run() {
getNumber();
}
public void getNumber() {
// synchronized (oj) {
lock.getLock();
String orderNumber = orderNumGenerator.getOrderNumber();
System.out.println("获取订单号:" + orderNumber);
lock.unLock();
// }
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(new OrderService()).start();
}
}
}
#####lock接口 ######
public interface Lock {
// 获取锁
public void getLock();
// 释放锁
public void unLock();
}
#####ZookeeperAbstractLock抽象类接口 ######
public abstract class ZookeeperAbstractLock implements Lock {
private static final String CONNECT_ADDRES = "192.168.110.159:2181,192.168.110.160:2181,192.168.110.162:2181";
protected ZkClient zkClient = new ZkClient(CONNECT_ADDRES);
protected String PATH = "/lock";
public void getLock() {
// 如果当前节点已经存在,则等待
if (tryLock()) {
System.out.println("获取到锁 get");
} else {
// 等待
waitLock();
// 重新获取锁
getLock();
}
}
protected abstract void waitLock();
protected abstract boolean tryLock();
public void unLock() {
if (zkClient != null) {
zkClient.close();
}
System.out.println("已经释放锁...");
}
#####ZookeeperAbstractLock抽象类接口 ######
//实现锁
public class ZookeeperDistrbuteLock extends ZookeeperAbstractLock {
private CountDownLatch countDownLatch = new CountDownLatch(1);
@Override
protected boolean tryLock() {
try {
zkClient.createEphemeral(PATH);
// 创建成功
return true;
} catch (Exception e) {
// 创建失败
return false;
}
}
@Override
protected void waitLock() {
try {
IZkDataListener iZkDataListener = new IZkDataListener() {
public void handleDataDeleted(String path) throws Exception {
// 唤醒等待线程, 继续往下走.
if (countDownLatch != null) {
countDownLatch.countDown();
}
}
public void handleDataChange(String path, Object data) throws Exception {
}
};
// 注册到zk监听中
zkClient.subscribeDataChanges(PATH, iZkDataListener);
if (zkClient.exists(PATH)) {
countDownLatch = new CountDownLatch(1);
// 等待
countDownLatch.await();
}
// 删除事件通知
zkClient.unsubscribeDataChanges(PATH, iZkDataListener);
} catch (Exception e) {
// TODO: handle exception
}
}
}
解决跨域的4中方案:
1.jsonp 缺点:只能支持get
2.设置响应头 ,referer
3.通过httpclient转发,缺点:比较麻烦,耗资源
4.nginx(反向代理) SpringCloud(API ZUUL)
0025 Dobbo
Dubbo架构图

利用zookeeper中的watch方法监听生产者的变化,并通知到消费者,redis也有这个机制,所以redis也可以实现这个功能

浙公网安备 33010602011771号