RedisBank 快速、准确且实时更新,只需在智能手机上轻扫几下,即可立即访问您的财务信息。随着手机银行从金融边缘进入主流,我们都已经习惯了随时随地将整个银行信息放在口袋里的想法。
为了响应这种向数字化的转变,Lars Rosenquist 构建了一个应用程序,让您可以创建自己的手机银行应用。通过使用 Redis,您的所有财务信息都将实时可用,使您能够准确监控、记录和规划财务。
让我们来看看 Lars 如何构建这个应用程序。但在深入了解这个应用的细节之前,我们想指出,您可以在 Redis Launchpad 上查看一系列令人兴奋的应用程序。
所以在这篇文章之后一定要去看看!
您将构建一个在线银行应用程序,它将为您提供银行账户的实时更新。使用 RedisBank,您将能够密切关注您的支出,并与金钱建立更健康的关系。
下面我们将逐步指导您完成构建过程,并重点介绍使此应用程序运行所需的所有组件。
准备好开始了吗?好的,让我们直接开始吧。
此应用程序还使用了一系列 Redis 核心数据结构和模块。其中包括
这是一个包含 API 和前端的 SpringBoot 应用程序。
git clone https://github.com/redis-developer/redisbank/
docker run -d --name redis-stack -p 6379:6379 redis/redis-stack-server
./mvnw clean package spring-boot:run
结果
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ redisbank ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /Users/ajeetraina/projects/redisbank/target/test-classes
[INFO]
[INFO] <<< spring-boot-maven-plugin:2.4.5:run (default-cli) < test-compile @ redisbank <<<
[INFO]
[INFO]
[INFO] --- spring-boot-maven-plugin:2.4.5:run (default-cli) @ redisbank ---
[INFO] Attaching agents: []
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.5)
导航到 http://localhost:8080 并使用以下凭据登录
请参考 此 文件获取凭据,因为这些值是为演示目的而硬编码的。
下面是登录页面的截图。
登录后,您将进入主门户页面(见下图)。
从这里,您将能够通过多种不同的门户功能更好地掌握您的财务状况。其中包括
Redis Streams 是一个只追加日志。数据生成应用会将交易放入流中,而应用程序将订阅此流并消费任何传入的交易,并通过 Websocket 连接将它们发送到前端。
前两个接口允许您实现 afterPropertiesSet() 方法和 destroy() 方法,您将使用它们来设置和清理对 Redis Stream 的订阅。
第三个接口要求您实现 nMessage(MapRecord<String,String, String> message),这是每当通过 Redis Stream 接收到新的银行交易时将执行的回调。
此时,您已订阅 Redis Stream。每当有新消息到达流时,将调用此类中的 onMessage(…) 方法。您仍然需要执行此方法,所以让我们看看如何完成。
if (subscription != null) {
subscription.cancel();
}
if (container != null) {
container.stop();
}
到目前为止,我们已经创建了一个 MessageListener 并订阅了银行交易的 Redis Streams,对于每个传入的银行交易,将其转发到 Stomp/Websocket 主题。
现在让我们看看这在我们的应用程序中是如何工作的。首先,在一个终端窗口中运行数据生成应用。该应用运行后,在另一个终端窗口中构建并运行该应用
./mvnw clean package
./mvnw spring-boot-run
此时两者都应该正在运行,因此导航到 http://localhost:8080 并使用 username/password 登录。您应该能够查看交易概览以及应用程序中一些尚未优化的区域(我们稍后会详细介绍)。
您应该会看到大约每十秒出现一次新交易。如果没有,请检查您的源代码,看看是否遗漏了任何注解。现在让我们看看如何添加搜索功能。
RediSearchCommands<String, String> commands = srsc.sync();
SearchOptions options = SearchOptions
.builder().highlight(Highlight.builder().field("description").field("fromAccountName")
.field("transactionType").tag(Tag.builder().open("<mark>").close("</mark>").build()).build())
.build();
SearchResults<String, String> results = commands.search(SEARCH_INDEX, term, options);
注意: 添加导入时,选择 com.redislabs 导入。
第一条语句创建一个使用 RediSearch 客户端库的 RediSearch 连接。第二条语句根据您的偏好创建 SearchOptions。第三条语句执行搜索并返回结果。
数据生成应用还会为每个账户的银行余额填充一个 TimeSeries。每当有新交易发生时,它都会更新。您可以查询此 TimeSeries 并将结果传递给用户界面,以便它可以在可视化图表中显示余额随时间的变化。现在让我们开始吧
String balance_ts_key = BALANCE_TS + principal.getName();
Map<String, String> tsValues = tsc.range(balance_ts_key, System.currentTimeMillis() - (1000 * 60 * 60 * 24 * 7),
System.currentTimeMillis());
Balance[] balanceTs = new Balance[tsValues.size()];
int i = 0;
for (Entry<String, String> entry : tsValues.entrySet()) {
Object keyString = entry.getKey();
Object valueString = entry.getValue();
balanceTs[i] = new Balance(keyString, valueString);
i++;
}
return balanceTs;
您在这里做的实质上是请求存储在 BALANCE_TS 键下的、从现在到(现在 - 1 周)之间的时间序列值。然后,您需要将结果复制到 Balance 数组中并返回。
您可能会注意到,您在这里使用 Principal 名称作为 TimeSeries 键的后缀。这意味着如果您使用不同的用户登录,它将是一个不同的键。
注意:在此示例中,我们没有使用额外的客户端库是有原因的。相反,我们扩展了 Lettuce 库,并提供了一个我们注入的接口。扩展 Lettuce 是将 Redis Module 功能添加到您的应用中,同时限制依赖项数量的绝佳方法。
将此功能添加到应用中将显示您的银行账户中最大的扣款方。因此,数据生成应用正在填充一个 Sorted Set。对于每笔交易,它会将交易值添加到 Sorted Set 的一个成员中,其中键是对手账户的名称以及该账户的总交易金额。
String biggestSpendersKey = SORTED_SET_KEY + principal.getName();
Set<TypedTuple<String>> range = redis.opsForZSet().rangeByScoreWithScores(biggestSpendersKey, 0,
Double.MAX_VALUE);
if (range.size() > 0) {
BiggestSpenders biggestSpenders = new BiggestSpenders(range.size());
int i = 0;
for (TypedTuple<String> typedTuple : range) {
biggestSpenders.getSeries()[i] = Math.floor(typedTuple.getScore() * 100) / 100;
biggestSpenders.getLabels()[i] = typedTuple.getValue();
i++;
}
return biggestSpenders;
} else {
return new BiggestSpenders(0);
}
这将根据成员的分数(从 0 到 Double.MAX_VALUE)检索 Sorted Set 的成员。然后,您将把结果放入 BiggestSpenders 对象中。
此时您应该正在运行,因此导航到 http://localhost:8080 并使用 username/password 登录。此时您将看到交易概览。
Redis Streams
数据生成应用大约每 10 秒生成一笔银行交易并将其放入流中。您可以使用以下命令查询该流:
xread count 10000 streams transactions_user 0-0
这将提供 transactions_username Stream 上的所有条目。请记住,您的应用通过 Spring Data 订阅了此流,因此每当向流中添加新元素时,它都会被应用处理并发送到用户界面。
Sorted Set
数据生成应用还会将每笔交易添加到 Sorted Set 中。这会将交易金额添加到分数中,累加每个账户名称的总交易金额并将其存储在有序集合中。然后,您只需像这样查询 Sorted Set 就可以识别出最大消费者:
zrangebyscore bigspenders_username 0 10000 withscores
TimeSeries
数据生成应用还会将银行账户余额添加到 TimeSeries 中,每当有新交易生成时。这使您可以使用如下查询来查看余额随时间的变化:
ts.range balance_ts_username 1623000000000 1653230682038 (use appropriate timestamps or it will return an empty array)
Hashes
每笔交易都作为 Hash 存储在 Redis 中,以便 RediSearch 可以对其进行索引。您将能够像下面的示例一样搜索每笔交易:
ft.search transaction_description_idx Fuel
ft.search transaction_description_idx Fuel highlight
ft.search transaction_description_idx Fuel highlight tags <mytag> </mytag>
会话数据
会话数据也存储在 Redis 中。这完全不需要您编写代码——只需添加依赖项即可。
spring.redis.host=your ACRE hostname
spring.redis.port=your ACRE port (default: 10000)
spring.redis.password= your ACRE access key
stomp.host=your ASC app endpoint URL (Default: <appname>-<service-name>.azuremicroservices.io)
stomp.port=443
stomp.protocol=wss
az spring-cloud app deploy -n acrebankapp -s acrebank -g rdsLroAcre --jar-path target/redisbank-0.0.1-SNAPSHOT.jar
使用以下代码获取应用程序登录信息:
az spring-cloud app logs -n acrebankapp -g rdsLroAcre -s acrebank
注意:该项目使用 JDK11 进行编译,因为它是 Azure Spring Cloud 支持的最高 LTS 版本。该项目也可以在本地或最高 JDK16 的其他平台上运行。
下面是一些您可能会遇到的已知问题:
手机银行是新常态,为了有效,它必须快速、便捷和准确。数字时代让我们都习惯了实时更新的无缝数字交互,未能满足这些期望将导致一个注定失败的次优应用程序。
但通过其先进的功能和低延迟,Redis 能够保证实时数据传输,消除任何延迟的可能性。只需在移动设备上轻点几下,用户就可以访问他们的银行信息,并获得对其财务状况的全面、准确了解。
要更直观地了解此应用程序是如何创建的,请务必查看 Lars 的 YouTube 视频。
如果您喜欢这篇文章,请务必访问 Redis Launchpad,您可以在那里找到各种影响日常生活的不同应用程序。
查看它。获得启发。加入 Redis 的乐趣!
Lars 在软件行业拥有丰富的经验,目前担任解决方案架构师经理,帮助他人发挥最大潜力。务必关注他的 GitHub 页面,以了解他的所有项目。