柚子快报邀请码778899分享:Dubbo+Zookeeper

http://yzkb.51969.com/

如果产品服务的业务量不是很大,业务又不是特别繁杂,功能模块的拆分颗粒度就不需要太细,也就没必要上微服务。因为微服务的运维治理复杂度及服务器资源开销代价是难以想象的。

本编简述下如何使用Dubbo+Zookeeper即可实现传统的分布式服务,并且支持高并发高可用场景下的动态扩容。

有关Dubbo的介绍,就无需多言了,它是一款高性能、轻量级的开源Java RPC框架(Remote Procedure Call Protocol 远程过程调用协议),它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

准备工作:

搭建springboot脚手架并成功运行,可参考历史分享springboot+mybatis 启动Zookeeper服务(作为Dubbo的服务注册协调中心)(搭建配置ZK服务,后续会在运维章节另行讲述)

1. maven添加Dubbo及ZK依赖

4.0.1 com.alibaba.boot dubbo-spring-boot-starter 0.2.0 org.apache.zookeeper zookeeper 3.4.13 com.github.sgroschupf zkclient 0.1 org.apache.curator curator-framework ${zk-curator.version} org.apache.curator curator-recipes ${zk-curator.version}

2.Dubbo配置

2.1 yml

#dubbodubbo: application:    name: demo-user registry:    address: zookeeper://192.168.2.7:2181?backup=192.168.2.8:2181,192.168.2.9:2181 file: /dubbo/demo-user/cache protocol: zookeeper check: false protocol: name: dubbo port: 28102 scan:    base-packages: com.demo.user.service.dubbo consumer: check: false timeout: 10000 retries: 0 #ZK locklock: zk-servers: 192.168.2.7:2181,192.168.2.8:2181,192.168.2.9:2181

2.2 开启dubbo服务注解扫描

import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;import org.springframework.boot.autoconfigure.SpringBootApplication;​@EnableDubbo@SpringBootApplicationpublic class DemoUserApplication {​ public static void main(String[] args) {        SpringApplication.run(DemoUserApplication.class, args); }​}

3.Dubbo调用

3.1 dubbo service provider

import lombok.extern.slf4j.Slf4j;import com.alibaba.dubbo.config.annotation.Service;​@Slf4j@Service // 注意该@Service注解是alibaba包下的,不要错引用了Spring包下的public class UserDubboServiceImpl implements UserDubboService {​}

3.2 dubbo service consumer

import com.alibaba.dubbo.config.annotation.Reference;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Service;​@Slf4j@Servicepublic class OrderServiceImpl extends BaseServiceImpl implements OrderService {     @Reference // 引用注入dubbo服务service bean  private UserDubboService userDubboService;}

4.ZK分布式锁

4.1 zk lock 配置

import lombok.extern.slf4j.Slf4j;import org.apache.curator.framework.CuratorFramework;import org.apache.curator.framework.CuratorFrameworkFactory;import org.apache.curator.framework.recipes.locks.InterProcessSemaphoreMutex;import org.apache.curator.framework.state.ConnectionState;import org.apache.curator.framework.state.ConnectionStateListener;import org.apache.curator.retry.ExponentialBackoffRetry;import org.springframework.beans.factory.InitializingBean;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Configuration;​import java.util.concurrent.TimeUnit;​/** * 分布式锁: * 注意该锁不能重入,即不可有嵌套锁*/@Slf4j@Configuration // 注意该组件需被springboot扫描注册成beanpublic class DistributedLock implements InitializingBean {​ private static CuratorFramework curator = null;​ private static ThreadLocal localLock = new ThreadLocal<>();​ @Value("${lock.zk-servers}") private String zkServers;​ private static final String basePath = "/lock/";​

  /**

  * bean添加到spring容器后,在完成bean实例化后才会执行该方法 

  */ @Override

  public void afterPropertiesSet() { if (curator == null) { curator = CuratorFrameworkFactory.builder().sessionTimeoutMs(30000).connectionTimeoutMs(30000) .retryPolicy(new ExponentialBackoffRetry(1000, Integer.MAX_VALUE)).connectString(zkServers).build(); curator.getConnectionStateListenable().addListener(new ZKListener()); curator.start(); } }​ /** * 不等待,遇锁直接退出 * * @param key * @return */ public static boolean acquire(String key) { try { InterProcessSemaphoreMutex lock = new InterProcessSemaphoreMutex(DistributedLock.curator, basePath + key); lock.acquire(); localLock.set(lock); } catch (Exception e) { log.warn("DistributedLock acquire error", e); return false; }​ return true; }​ /** * 排队等待 * * @param key * @param timeout * @return */ public static boolean acquire(String key, long timeout) { try { InterProcessSemaphoreMutex lock = new InterProcessSemaphoreMutex(DistributedLock.curator, basePath + key); lock.acquire(timeout, TimeUnit.SECONDS); localLock.set(lock); } catch (Exception e) { log.warn("DistributedLock acquire error", e); return false; }​ return true; }​ /** * 排队等待 * * @param key * @param timeout * @return */ public static boolean acquire(String key, long timeout, TimeUnit unit) { try { InterProcessSemaphoreMutex lock = new InterProcessSemaphoreMutex(DistributedLock.curator, basePath + key); lock.acquire(timeout, unit); localLock.set(lock); } catch (Exception e) { log.warn("DistributedLock acquire error", e); return false; }​ return true; }​ /** * 释放锁 */ public static void release() { try { InterProcessSemaphoreMutex lock = localLock.get(); if (lock != null && lock.isAcquiredInThisProcess()) { lock.release(); } } catch (Exception e) { log.warn("DistributedLock release error", e); } }​ /** * zk监听器 */ public class ZKListener implements ConnectionStateListener {​ @Override public void stateChanged(CuratorFramework client, ConnectionState state) { if (ConnectionState.LOST.equals(state)) { // 连接丢失 log.warn("==ZK LOCK== DistributedLock lost session with zookeeper"); } else if (ConnectionState.CONNECTED.equals(state)) { // 连接新建 log.warn("==ZK LOCK== DistributedLock connected with zookeeper"); } else if (ConnectionState.RECONNECTED.equals(state)) { // 重新连接 log.warn("==ZK LOCK== DistributedLock reconnected with zookeeper"); } }​ }​ /** * 分布式锁业务类型 */ public enum LockType {        PRODUCT_INVENTORY }​}

4.2 zk lock 使用

    // 加锁,    String lockKey = DistributedLock.LockType.PRODUCT_INVENTORY + "/" + productId; try{ if(DistributedLock.acquire(lockKey, 3)){           // todo something 抢购排队下单,扣减商品库存 } }catch(Exception e){ log.error("userId = {}, couponId = {}, 下单失败:{}", userId, productId, e.getMessage()); throw new Exception("下单失败", e); }finally{ DistributedLock.release(); }​    // service 方法中抛出异常,回滚事务 throw new CommonException("下单失败");

5.CAP理论

一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项,也即不可能三角CAP理论。

既然是分布式服务,自然需要具备分区容错性。除此之外,用户更多的是需要服务的可用性,至于一致性方面,目前常用的折中解决方案是,选择最终一致性​。​

以上关于后端服务常用的框架技术及一些相关中间件都已整理完毕,后续会更新基于SpringCloud Alibaba的微服务有关章节。

柚子快报邀请码778899分享:Dubbo+Zookeeper

http://yzkb.51969.com/

推荐阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。