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也可以实现这个功能

 

posted @ 2020-02-21 23:34  余***龙  阅读(129)  评论(0)    收藏  举报