如非授权,禁止用于商业用途,转载请注明出处
作者:mynewworldyyl

往下看前,建议完成前面1到12小节

1. 微服务中ID地位

如果说前面小节的功能点是微服务的大脑,那么全局唯一ID则是微服务的神经系统,没有ID这个神经系统,再强的大脑也白搭,只有有了这个神经系统,才能有效协调整个微服务系统的正常工作,才不会出现神经错乱。就好像两个或多个人的身份证号码相同,则依赖于这个身份证号唯一性的系统就无法正常工作(无法为具有相同身份证号的这些人服务)。

JMicro中,消息是微服务之间通讯最基本单元,系统将之命名为org.jmicro.api.net.Message,每个消息由唯一ID所标识,不管系统中有多少个服务,服务之间以多高的QPS做交互,也许上万亿的QPS,也不管系统运行多久,也许是1亿年,假设这1亿年中总共有万万亿个消息,那么这万万亿个消息的ID都不能重复,否则这个微服务系统都是不可靠的。例如,两个转账消息,一个转1分钱,一个传1亿,如果两个消息ID相同,那么有50%的可能本应收到1亿的账号却收到了1分钱,而那个本应收到1分钱账号却收到了1亿,如果是比特币转账,那后果就凉了。

2. JMicro中ID使用场景

最典型的是服务调用链路跟踪(【6】JMicro微服务-服务日志监控  ),从调用发起方开始,生成一个全局唯一链路ID,并且将这个链路ID从调用者传给被调用者,直到最终被调用者返回时,也将链路ID返回,直到返回给调用发起方。JMIcro通过将相同的链路ID消息归属为一个微服务调用过程,这个相同ID的链路上发生的所有事件及相关统计数据,都可以通过这个ID作为维度做跟踪分析。比如从调用发起方发送请求到收到响应,消耗很长时间,那么通过链路ID查看每个消息请求和响应时间,即可找到问题的结点,这里的“结点”即是JMicro服务。

还有就是JMicro的RPC调用过程中,为了提高性能,消息都是异步的,但是作为RPC客户端调用者,却是同步的方式使用,比如前面的ISimpleRpc调用hello服务方法,返回一个字符串,是同步返回的。这个底层异步消息提供上层同步使用,就是通过请求ID实现的。每个RPC请求,会生成一个全局唯一ID,并将这个ID传给服务方,服务方处理完成后,也返回给调用方,调用方底层通过这个ID识别这个结果应该返回给那个RPC方法(唤醒调用者线程)。

3. 应用全局唯一ID

应用如果需要使用到全局唯一ID,也可以和JMicro底层一样,使用相同接口,如下代码是JMicro获取当前链路ID代码。

 public static Long lid(){
         JMicroContext c = get();
         Long id = c.getLong(LINKER_ID, null);
         if(id != null) {
             return id;
         }

         ComponentIdServer idGenerator = JMicro.getObjectFactory().get(ComponentIdServer.class);

         if(idGenerator != null) {
             id = idGenerator.getLongId(Linker.class);
             c.setLong(LINKER_ID, id);
         }
         return id;
     }

2到6行检查当前上下文是否有链路ID,如果有则直接返回,否则第8行取得ComponentIdServer 实例,并通过ComponentIdServer实例的相关方法获取Linker.class的

ID,下图为ComponentIdServer实例获取ID相关方法:

3种类型6个方法,分别为int类型ID,获取1个id和多个ID两个方法,同理Long和String。

取得ComponentIdServer 实例的另一种方式如下,通过@Inject注解获取:

@Inject
private ComponentIdServer idGenerator;

4. 基于Redis全局唯一ID生成方案

如下代码为基于Redis的lua脚本,获取特定KEY的cnt个ID,使用了Redis调用Lua脚本的原子性。

public JMicroRedisBaseIdGenerator() {
        StringBuilder sb = new StringBuilder();
        sb.append("local k = KEYS[1];\n");
        sb.append("local cnt = ARGV[1];\n");
        sb.append("local val = tonumber(redis.call('incrby', k, cnt));\n");
        sb.append("return val;\n");
        luaScript = sb.toString();
    }

获取Int类型的ID

public Integer[] getIntIds(String idKey, int num) {
        Jedis r = pool.getResource();
        try {
            int endId = Integer.parseInt(r.eval(luaScript, 1, idKey,num+"").toString());
            Integer[] ids = new Integer[num];
            int oriId = endId - num;
            for(int i = 0; i < num; i++) {
                ids[i] = oriId+i;
            }
            return ids;
        }finally {
            r.close();
        }
    }

5. 使用Redis

在org.jmicro.redis.RegistRedis中,有如下方法实现将Redis相关接口实例注册到IObjectFactory中

所以我们可以通过@Inject将以上实例对象注入到我们的代码中,如下代码所示:

    @Inject(required=true)
    private JedisPool pool;

到目前为止,我们在JMIcro环境中,自动拥有了ZK及Redis环境支持,后面还会有MyBatis相关支持,用以操作数据库,如果有兴趣,可提前通过源码查看JMIcror插件式的模块扩展机制。Github链接如下:

https://github.com/mynewworldyyl/jmicro/tree/master/jmicro.ext/jmicro.mybatis

https://github.com/mynewworldyyl/jmicro/tree/master/jmicro.redis

https://github.com/mynewworldyyl/jmicro/tree/master/jmicro.zk

【1】JMicro微服务-RPC体验

【2】JMicro微服务-Hello World

【3】JMicro微服务-服务超时,重试,重试间隔

【4】JMicro微服务-服务限流

【5】JMicro微服务-熔断降级

【6】JMicro微服务-服务日志监控

【7】JMicro微服务-服务路由,负载均衡

【8】JMicro微服务-JMicro ZKUI

【9】JMicro微服务-发布订阅消息服

【10】JMicro微服务-API网关

【11】JMicro微服务-配置管理

【12】JMicro微服务-Zookeeper

【13】JMicro微服务-ID生成与Redis的更多相关文章

  1. 【2】JMicro微服务-Hello World

    如非授权,禁止用于商业用途,转载请注明出处作者:mynewworldyyl 1. 首先完成 JMicro微服务-RPC体验 的1到5步. 按默认方式启动ZK及Redis: JDK需要Java8及以上. ...

  2. 微服务架构中的Redis

    了解如何将Redis与Spring Cloud和Spring Data一起使用以提供配置服务器,消息代理和数据库. Redis可以广泛用于微服务架构中.它可能是少数流行的软件解决方案之一,你的应用程序 ...

  3. 【12】JMicro微服务-Zookeeper

    如非授权,禁止用于商业用途,转载请注明出处作者:mynewworldyyl 往下看前,建议完成前面1到11小节 1. CuratorFramework支持 JMicro目前基于Zookeeper实现统 ...

  4. 【11】JMicro微服务-配置管理

    如非授权,禁止用于商业用途,转载请注明出处作者:mynewworldyyl 往下看前,建议完成前面1到10小节 JMicro目前仅支持基于Zookeeper做配置管理,全部配置信息可以在ZK做增删改查 ...

  5. 【10】JMicro微服务-API网关

    如非授权,禁止用于商业用途,转载请注明出处作者:mynewworldyyl 往下看前,建议完成前面1到9小节 1. Api网关基本特性: Api网关作为对外网提供服务的基本入口,地位类似于NGINX, ...

  6. 【8】JMicro微服务-JMicro ZKUI

    ZKUI是一个开源项目,是一个查看,修改ZK数据非常方便的工具.JMicro基于ZK做服务治理,配置管理,因此使用ZKUI会提供非常大的方便. Github地址:https://github.com/ ...

  7. 【3】JMicro微服务-服务超时,重试,重试间隔

    如非授权,禁止用于商业用途,转载请注明出处作者:mynewworldyyl 接下来的内容都基于[2]JMicro微服务-Hello World做Demo 微服务中,超时和重试是一个最基本问题下面Dem ...

  8. JMicro微服务之超时&重试

    JMicro是本人开发的基于Java实现的微服务框架,当前正式版本为0.0.3,并已发布到maven中央仓库.项目源码github:https://github.com/mynewworldyyl/j ...

  9. 你还在手撕微服务?快试试 go-zero 的微服务自动生成

    0. 为什么说做好微服务很难? 要想做好微服务,我们需要理解和掌握的知识点非常多,从几个维度上来说: 基本功能层面 并发控制&限流,避免服务被突发流量击垮 服务注册与服务发现,确保能够动态侦测 ...

随机推荐

  1. <asp:RadioButton> 选项判断

    小菜在项目中遇到一个<asp:RadioButton> 选择之后,让其控制其他标签显示或者隐藏的问题.记录以备忘记之需! <html xmlns="http://www.w ...

  2. 如何配置JDK?

    有很多人,java都下载好,却因不会配置JDK,而无法编程.今天巩固就来教大家配置JDK.​ 第一步:将下载好的java放在D盘(最好不要占用C盘).​​​ 第二步:右击我的电脑,选择"属性 ...

  3. delphi XE7 数组操作中缺少的find(POS)功能

    delphi xe7 中对数组操作做了很多扩充,比如加入了类似字符串处理的功能. 例如,数组相加 var A: array of integer; B: TBytes = [1,2,3,4]; //I ...

  4. 常见的web服务器软件分类

    (1)ApacheApache是世界使用排名第一的Web服务器软件.它可以运行在几乎所有广泛使用的计算机平台上.Apache源于NCSAhttpd服务器,经过多次修改,成为世界上最流行的Web服务器软 ...

  5. 2018.10.18 bzoj1185: [HNOI2007]最小矩形覆盖(旋转卡壳)

    传送门 不难看出最后的矩形一定有一条边与凸包某条边重合. 因此先求出凸包,然后旋转卡壳求出当前最小矩形面积更新答案. 代码: #include<bits/stdc++.h> #define ...

  6. 2018.09.15点名器(简单dp)

    描述 Ssoier在紧张的学习中,杜老师每天给他们传授精妙的知识. 杜老师为了活跃气氛,设计了一个点名器,这个点名器包含一个长度为M的数组(下标1开始),每个元素是一个oier的名字,每次点名的时候, ...

  7. gj12-1 协程和异步io

    1 并发.并行.同步.异步.阻塞.非阻塞 并发.并行 并发是报一个时间段内有几个程序在同一个cpu上运行,但是任意时刻只有一个程序在cpu上运行.在一个时间段内某一个请求很快,能够响应的用户就越多,高 ...

  8. 基于Verilog HDL的二进制转BCD码实现

    在项目设计中,经常需要显示一些数值,比如温湿度,时间等等.在数字电路中数据都是用二进制的形式存储,要想显示就需要进行转换,对于一个两位的数值,对10取除可以得到其十位的数值,对10取余可以得到个位的数 ...

  9. Dreamweaver杀手!Illustrator终结者?Flash的末日?图形图像设计程序之网页版

    Dreamweaver杀手!Illustrator终结者?Flash的末日?图形图像设计程序之网页版 阅读:  评论:  作者:Rybby  日期:  来源:rybby.com Adobe 家的 Il ...

  10. java web 入门实例servlet篇(显示后台数据库列表,删除某一条记录并显示)

    编写过程中需要注意的问题: 1.建立eclipse动态web工程时,需要改写编译后class文件的位置,通常情况下是这个位置:/WebContent/WEB-INF/classes 2.配置的页面链接 ...