如何让 J2Cache 在多种编程语言环境中使用

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介:

现在的系统是越来越复杂了,不仅仅是功能复杂,系统结构也非常复杂,而且经常在一个系统里包含几种不同语言编写的子系统。例如用 JavaScript 做前端开发、用 Java/PHP 等等做后端,C/C++/Go 等做一些底层模块等等(我只是举个栗子,不要挑起斗争哦)。

这些不同语言编写的子系统经常需要进行一些交互,多数方面的数据交互一般都有对应的技术或者中间件来解决,例如消息中间件、数据库、RESTful 接口、Redis 等等。

本文主要聚焦于缓存系统的交互。

在多语言开发的系统中,使用 Redis 这类服务实现缓存交付是非常适合的,但前提是缓存的数据必须是每一种语言都能识别。基于这个前提来考量,JSON、XML 是最合适的格式,因为它们是语言无关的规范,任何语言都能方便的解析这两种格式。而 JSON 相比 XML 又更优一些,因为同样数据用 JSON 表示体积更小。

所以 Redis + JSON 就成为了跨语言环境中的缓存首先解决方案。不过我之前一直在强调单独使用 Redis 做缓存的严重问题(详情):巨大的缓存数据吞吐量会导致 Redis 的数据读取变得异常缓慢,而扩容 Redis 的成本又非常高。

因此我们有必要在跨语言环境中使用 J2Cache 。

那么问题来了,J2Cache 是一个 Java 开发的缓存桥梁,非 Java 语言的应用怎么用 J2Cache 呢?答案是用不了!

但是可行!

我们假设一个系统中包含两个应用,一个 Java 开发(J应用),另外一个随便用什么别的语言开发,例如 Python (P应用)?

J应用和 P应用之间需要进行缓存交互,在 J2Cache 中,两个节点之间的数据交互包括:

  1. 缓存数据
  2. 消息通知

J2Cache 从 2.0 版本开始就是用 JSON 格式的消息通知,默认走 Redis 的 Pub/Sub 来传播,因此 P应用只需要连接到 Redis 对应的 Pub/Sub 通道就可以获取和发布消息通知。

最大的问题是“缓存数据”,因为应用系统中的缓存数据一般会比较复杂,例如我们会缓存一个对象、一个列表、数组等等。在 Java 应用中我们在将这些数据写到 Redis 时一般是采用序列化的方式,而你让其他语言来读取 Java 序列化数据是很难,可以说是几乎不可能的。

因此我们也必须用 JSON 的格式来表示我们所要缓存的数据,这样就可以让别的语言方便的解析数据。

在 J2Cache 中是需要配置 j2cache.serialization = json 即可实现这个需求。

J2Cache 使用的是 FST 库提供的 JSON 序列化方案,来看看一个普通对象序列化后的结果:

首先是要序列化的类:

public class Person implements Serializable {

    private String name;
    private int age;
    private BigInteger seconds = new BigInteger("100");
    private List<School> schoolList;
    private HashMap<String, Integer> jobs;

}

public class School implements Serializable {

    private String name;
    private int random = (int)(Math.random() * 1000);

}

初始化的数据:

person = new Person();
person.setName("Winter Lau");
person.setAge(19);
person.setSchoolList(Arrays.asList(new School("西北工业大学"), new School("泉州第五中学"), new School("城东中学"), new School("洛南小学")));
person.setJobs(new HashMap<String, Integer>(){{
    put("creawor", 3);
    put("moabc", 5);
    put("huateng", 3);
    put("oschina", 8);
}});

序列化的结果:

{"@type":"net.oschina.j2cache.Person","@object":{"age":19,"seconds":{"@type":"java.math.BigInteger","@object":[1,["byte",100]]},"create_time":{"@type":"date","@object":[1539737786400]},"jobs":{"@type":"map","@object":[4,"creawor",3,"huateng",3,"moabc",5,"oschina",8]},"schoolList":{"@type":"list","@object":[4,{"@type":"net.oschina.j2cache.School","@object":{"random":950,"name":"西北工业大学"}},{"@type":"net.oschina.j2cache.School","@object":{"random":983,"name":"泉州第五中学"}},{"@type":"net.oschina.j2cache.School","@object":{"random":647,"name":"城东中学"}},{"@type":"net.oschina.j2cache.School","@object":{"random":766,"name":"洛南小学"}}]},"name":"Winter Lau"}}

而消息通知的数据更为简单:

{"keys":[],"operator":1,"src":6160636}

所以,当我们用其他语言来编写缓存操作的时候,只需要参考 J2Cache 的流程对这两种 JSON 格式的数据进行解析即可。

有兴趣的朋友可以根据本文的思路来开发不同语言版本的 J2Cache ,我之前已经开发了一个 Python 的版本的雏形 —— Py3Cache

本文来自云栖社区合作伙伴“开源中国”

本文作者:红薯

原文链接

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3月前
|
存储 缓存 安全
Go 简单设计和实现可扩展、高性能的泛型本地缓存
本文将会探讨如何极简设计并实现一个可扩展、高性能的本地缓存。支持多样化的缓存策略,例如 最近最少使用(LRU)等。
71 0
Go 简单设计和实现可扩展、高性能的泛型本地缓存
|
9月前
|
人工智能 Java 数据挖掘
Python内存管理解析:高效利用资源的关键
Python内存管理解析:高效利用资源的关键
126 0
|
9月前
|
存储 缓存 BI
|
11月前
|
存储 开发框架 安全
在 C# 中使用 Span<T> 和 Memory<T> 编写高性能代码
在 C# 中使用 Span 和 Memory 编写高性能代码 .NET 中支持的内存类型 .NET Core 2.1 中新增的类型 访问连续内存: Span 和 Memory Span 介绍 C# 中的 Span Span 和 Arrays Span 和 ReadOnlySpan Memory 入门 ReadOnlyMemory Span 和 Memory 的优势 连续和非连续内存缓冲区 不连续的缓冲区: ReadOnly 序列 实际场景 Benchmarking 基准测试 安装 NuGet 包 Benchmarking Span 执行基准测试 解读基准测试结果 Span 限制 结论
253 0
|
自然语言处理 Java API
PHP 语言的核心组成部分有哪些?底层原理是什么?
PHP 语言的核心组成部分有哪些?底层原理是什么?
144 0
|
Java Go 调度
go 语言中的并发特性
go 语言中的并发特性
|
自然语言处理 程序员 编译器
面向对象基础学习路径&amp;编程语言历史|学习笔记
快速学习面向对象基础学习路径&amp;编程语言历史
58 0
|
存储 Rust Java
【Rust 指南】详解Rust所有权的语法机制 | 理解其独特的内存管理原理
【Rust 指南】详解Rust所有权的语法机制 | 理解其独特的内存管理原理
297 0
【Rust 指南】详解Rust所有权的语法机制 | 理解其独特的内存管理原理
|
XML JavaScript 前端开发
在FreeSWITCH中执行长期运行的嵌入式脚本–Lua语言例子
众所周知,FreeSWITCH中可以使用嵌入式的脚本语言javascript、lua等来控制呼叫流程。而更复杂一点操作可能就需要使用Event Socket了。其实不然,嵌入式的脚本也可以一直运行,并可以监听所有的Event,就像使用Event Socket起一个单独的Daemon一样。
|
前端开发 程序员 C#
程序人生 - 这几门语言可能要被淘汰了!
程序人生 - 这几门语言可能要被淘汰了!
121 0
程序人生 - 这几门语言可能要被淘汰了!