zookeeper-4使用场景

1. Zookeeper 非公平锁/公平锁/共享锁
2. Spring Cloud Zookeeper注册中心实战
 

Zookeeper 分布式锁加锁原理

 上面的图示加锁有个弊端:并发量大的话,性能会下降的比较厉害,主要原因是,所有的连接
都在对同一个节点进行监听,当服务器检测到删除事件时,要通知所有的连接,所有的连接同时
收到事件,再次并发竞争,这就是羊群效应。这种加锁是非公平锁的实现。

 借助于临时顺序节点,可以避免同时多个节点的并发竞争锁,缓解了服务端压力。这种实
现方式所有加锁请求都进行排队加锁,是公平锁的具体实现

分布式锁的核心代码:

引入依赖

<dependency>
 <groupId>org.apache.curator</groupId>
 <artifactId>curator-recipes</artifactId>
 <version>5.0.0</version>
 <exclusions>
    <exclusion>
       <groupId>org.apache.zookeeper</groupId>
       <artifactId>zookeeper</artifactId>
    </exclusion>
 </exclusions>
</dependency>
<dependency>
 <groupId>org.apache.zookeeper</groupId>
 <artifactId>zookeeper</artifactId>
 <version>3.5.8</version>
</dependency>

减库存操作:

@Transactional
 public void reduceStock(Integer id){
    Product pro= proMapper.getProduct(id);
    if (pro.getSto() <=0 ) {
        throw new BusiessException("库存不足");
    }
    int i = proMapper.decStock(id);
    if (i==1){
        Order order = new Order();
        order.setUserId(UUID.randomUUID().toString());
        orderMapper.insert(order);
    }else{
        throw new RuntimeException("新增订单失败");
    }
}

上面代码有个问题:当并发量较大就会导致扣减库存变为负数

用zk分布式锁curator来解决

初始化curator:注意这个start方法一定要

@Bean(initMethod = "start")
public CuratorFramework curatorFramework(){
    RetryPolicy retryPolicy = new ExponentialBackoffRetry(10000, 5);
    CuratorFramework client = CuratorFrameworkFactory.newClient("192.168.25.111:2181", retryPolicy);
    return client;
}

加锁操作:

@Autowired
CuratorFramework curatorFramework;

@PostMapping("/deduct")
public Object reduceStock(Integer id) throws Exception {
    InterProcessMutex interProcessMutex = new InterProcessMutex(curatorFramework, "/product_" + id);
    try {
        interProcessMutex.acquire();
        orderService.reduceStock(id);
    } catch (Exception e) {
            throw e;
    }finally {
        //注意一定要释放锁
        interProcessMutex.release();
    }
    return "ok";
}

二:注册中心

引入依赖

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>

添加注册中心地址

#zookeeper 连接地址
spring.cloud.zookeeper.connect-string=192.168.25.111:2181
#将本服务注册到zookeeper
spring.cloud.zookeeper.discovery.register=true
spring.cloud.zookeeper.session-timeout=30000

利用ApplicationRunner的特性:应用已启动就会回调run方法,往zk注册中心注册节点

public void run(ApplicationArguments args) throws Exception {
    //应用启动的时候往zk注册中心注册/first/second的节点
    ZookeeperRegistration registration = ServiceInstanceRegistration.builder()
            .defaultUriSpec()
            .address("all")
            .port(10000)
            .name("/first/second")
            .build();
    this.serviceRegistry.register(registration);
}

客户端的操作:

注册负载均衡器

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    RestTemplate restTemplate = new RestTemplate();
     return restTemplate;
}
@Autowired
private LoadBalancerClient loadBalancerClient;

@GetMapping("/zk")
public String zk() {
     //直接调用
    return this.restTemplate.getForObject("http://product/Info", String.class);
}

这就是注册中心的用法,非常简单

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值