栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Dubbo+Zookeeper

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Dubbo+Zookeeper

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

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


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

准备工作:

  1. 搭建springboot脚手架并成功运行,可参考历史分享springboot+mybatis

  2. 启动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/";​

        @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();        }    }​        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;    }​        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;    }​        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);        }    }​        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的微服务有关章节。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1027634.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号