.net core实践系列之短信服务-架构优化

前言

通过前面的几篇文章,讲解了一个短信服务的架构设计与实现。然而初始方案并非100%完美的,我们仍可以对该架构做一些优化与调整。

同时我也希望通过这篇文章与大家分享一下,我的架构设计理念。

源码地址:https://github.com/SkyChenSky/Sikiro.SMS/tree/optimize (与之前的是另外的分支)

架构是设计的还是演变的?

架构

该词出自于建筑学。软件架构定义是指软件系统的基础结构,是系统中的实体及实体(服务)之间的关系所进行的抽象描述。而架构设计的目的是为了解决软件系统复杂度带来的问题。

复杂度

系统复杂度主要有下面几点:

  • 高可用

  • 高性能

  • 可扩展

  • 安全性

  • 维护成本

  • 用户规模

业务规模

系统的复杂度导致的直接原因是业务规模。为了用户流畅放心的使用产品,不得不提高系统性能与安全。当系统成为人们生活不可缺一部分时,避免机房停电、挖掘机挖断电缆导致的系统不可用,不得不去思考同城跨机房同步、异地多活的高可用方案。

答案并非二选一

我认为架构,需要在已知可见的业务复杂度与用户规模的基础上进行架构设计;伴随着技术积累与成长而对系统进行架构优化;用户的日益增长,业务的不断扩充,迫使了系统的复杂度增加,为了解决系统带来新的复杂度而进行架构演变。

因此,架构方案是在已有的业务复杂度、用户规模、技术积累度、人力时间成本等几个方面的取舍决策后的结果体现。

原架构

640?wx_fmt=png

缺点分析

  • 一般情况下,调度任务轮询数据库,90%的动作是无用功,频繁的数据库访问会对数据库增加不少压力。

  • 为了让调度任务服务进行轮循数据,需要在API优先进行数据持久化,这无疑是降低了API的性能。

  • MongoDB的Update操作相比于Insert操作时低效的,对于日志类数据应增量添加。

因此从上述可见,调度任务服务这块是优化关键点所在。

新架构图

640?wx_fmt=png

  • 使用了RabbitMQ的队列定时任务代替调度任务来实现定时发送。

  • 抛弃了调度任务,减少了调用链,同时也减少了应用服务数据量。

  • 对SMS集合在MongoDB里进行按年月的时间划分,对于日志类数据可以在有效的时间范围外进行方便的归档、删除。同时也避免了同集合的数据量过大导致的查询效率缓慢。

队列定时任务

RabbitMQ自身并没有定时任务,然而可以通过消息的Time-To-Live(过期时间)与Dead Letter Exchange(死信交换机)的结合模拟定时发布的功能。具体原理如下:

  • 生产者发布消息,并发布到已申明消息过期时间(TTL)的缓存队列(非真正业务消费队列)

  • 消息在缓存队列等待消息过期,然后由Dead Letter Exchange将消息重新分配到实际消费队列

  • 消费者再从实际消费队列消费并完成业务

 

 640?wx_fmt=png

Dead Letter Exchange

Dead Letter Exchange与平常的Exchange无异,主要用于消息死亡后通过Dead Letter Exchange与x-dead-letter-routing-key重新分配到新的队列进行消费处理。

消息死亡的方式有三种:

  • 消息进入了一条已经达到最大长度的队列

  • 消息因为设置了Time-To-Live的导致过期

  • 消息因basic.reject或者basic.nack动作而拒绝

Time-To-Live

两种消息过期的方式:

队列申明x-message-ttl参数

var args = new Dictionary<string, object>();
args.Add("x-message-ttl", 60000);
model.QueueDeclare("myqueue", false, false, false, args);

每条消息发布声明Expiration参数

640?wx_fmt=png

RabbitMQ.Client队列定时任务Demo

640?wx_fmt=png

640?wx_fmt=png

Sikiro.SMS实现优化

上面介绍了队列定时任务基本原理,然而我们需要自己的项目进行修改优化。

API消息发布

EasyNetQ是一款非常良好使用性的RabbitMQ.Client封装。对队列定时任务他也已经提供了相应的方法FuturePublish给我们使用。

然而他的FuturePublish由有三种调度方式:

  • DeadLetterExchangeAndMessageTtlScheduler

  • DelayedExchangeScheduler

  • ExternalScheduler

DelayedExchangeScheduler是需要EasyNetQ项目提供的调度程序,本质上也是轮询

ExternalScheduler是通过使用MQ的插件。

DeadLetterExchangeAndMessageTtlScheduler才是我们之前通过DEMO实现的方式,在EasyNetQ组件上通过下面代码进行启用。

services.RegisterEasyNetQ(_infrastructureConfig.Infrastructure.RabbitMQ, a =>{a.EnableDeadLetterExchangeAndMessageTtlScheduler();});

下面代码是Sikiro.SMS.Api的优化改造:

640?wx_fmt=png

重发机制

重发一般是请求服务超时的情况下使用。而导致这种原因的主要几点是网络波动、服务压力过大。因为前面任意一种原因都无法在短时间恢复,因此对于简单的重试 类似while(i<3)ReSend() 是没有什么意义的。

因此我们需要借助队列定时任务+发送次数*延迟时间来完成有效的非频繁的重发。

640?wx_fmt=png

SMS日志集合维度

SMS日志作为非必要业务的运维型监控数据,在需要的时候随时可以对此进行删除或者归档处理。因此以时间(年月)作为集合维度,可以很好的对日志数据进行管理。

mongoProxy.Add(MongoKey.SmsDataBase, MongoKey.SmsCollection + "_" + DateTime.Now.ToString("yyyyMM"), model);

结束

经过本系列6篇的文章,介绍了以短信服务为业务场景,基于.net core平台的一个简单架构设计、架构优化与服务实现的实践例子。希望我的分享能帮助有需要的朋友。如果有任何好的建议请到下方给我留言。

相关文章:

  • .net core实践系列之短信服务-为什么选择.net core(开篇)

  • .net core实践系列之短信服务-架构设计

  • .net core实践系列之短信服务-Sikiro.SMS.Api服务的实现

  • .net core实践系列之短信服务-Sikiro.SMS.Job服务的实现

  • .net core实践系列之短信服务-Api的SDK的实现与测试

原文地址: https://www.cnblogs.com/skychen1218/p/9565198.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319886.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Poj 1061 青蛙的约会

Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 143491 Accepted: 33018 Description 文章目录题目&#xff1a;思路:代码:题目传送题目&#xff1a; 两只青蛙在网上相识了&#xff0c;它们聊得很开心&#xff0c;于是觉得很有必要见一面。它们很高兴地发现它们住…

P3649-[APIO2014]回文串【PAM】

正题 题目链接:https://www.luogu.com.cn/problem/P3649 题目大意 一个字符串&#xff0c;求最大的回文串长度出现次数 解题思路 构建出PAM\text{PAM}PAM然后统计一下每个节点作为后缀的次数&#xff0c;failfailfail树上上传一下信息就好了&#xff0c;时间复杂度O(n)O(n)O…

【数学】拉格朗日插值(luogu 4781/金牌导航 拉格朗日插值-1)

拉格朗日插值 luogu 4781 金牌导航 拉格朗日插值-1 题目大意 给出n个点&#xff0c;让你确定经过这n个点且不超过n-1次的方程&#xff0c;现在给出k&#xff0c;让你求出其函数值 样例#1 输入样例#1 3 100 1 4 2 9 3 16输出样例#1 10201样例#2 输入样例#2 3 100 1 1 …

游戏 (博弈论)

https://blog.csdn.net/Mys_C_K/article/details/91443390

.NET Core中Object Pool的简单使用

前言复用&#xff0c;是一个重要的话题&#xff0c;也是我们日常开发中经常遇到的&#xff0c;不可避免的问题。举个最为简单&#xff0c;大家最为熟悉的例子&#xff0c;数据库连接池&#xff0c;就是复用数据库连接。那么复用的意义在那里呢&#xff1f;简单来说就是减少不必…

数论 欧几里得与扩展欧几里得

欧几里得算法&#xff1a; 求a&#xff0c;b的最大公约数 gcd&#xff08;a,b&#xff09; gcd(b,a%b) ll gcd(ll a,ll b) {return b0?a:gcd(b,a%b); }扩展欧几里得算法&#xff1a; 如果a&#xff0c;b是整数&#xff0c;一定存在x和y使得axbygcd&#xff08;a&#xff0c…

P4173-残缺的字符串【FFT】

正题 题目链接:https://www.luogu.com.cn/problem/P4173 题目大意 给出两个字符串S,TS,TS,T&#xff0c;其中包含小写字母和一些???&#xff0c;???可以匹配任何字符。 求有多少个ppp使得T0∼∣t∣−1Sp∼p∣t∣−1T_{0\sim |t|-1}S_{p\sim p|t|-1}T0∼∣t∣−1​Sp∼…

转圈游戏(luogu 1965)

转圈游戏 luogu 1965 题目大意 求(xm10k)%n(x m\times 10^k)\%n(xm10k)%n 输入样例 10 3 45输出样例 5数据范围 1<n<10000000<m<n,1⩽x⩽n,0<k<1091<n<10000000<m<n,1\leqslant x\leqslant n,0<k<10^91<n<10000000<m<n…

.Net Core应用框架Util介绍(三)

上篇.Net Core应用框架Util介绍&#xff08;二&#xff09;介绍了Util的开发环境&#xff0c;并让你把Demo运行起来。本文将介绍该Demo的前端Angular运行机制以及目录结构。目录结构在VS上打开Util Demo&#xff0c;会看见如下的目录结构。现代前端通常采用VS Code开发&#xf…

【DP】字串距离(luogu 1279)

字串距离 luogu 1279 题目大意 给出两个字符串&#xff0c;让你加上若干空格&#xff0c;使其长度相同 对于第i位&#xff0c;如果都是字母那代价就是ASCII码的差值&#xff0c;如果一个是字母那就是k&#xff0c;如果没有一个是字母那就是0&#xff0c;让你求最小代价 输入…

hdu 1525 Euclid‘s Game

hdu 1525 文章目录Problem Description题意&#xff1a;题解&#xff1a;代码&#xff1a;Problem Description Two players, Stan and Ollie, play, starting with two natural numbers. Stan, the first player, subtracts any positive multiple of the lesser of the two n…

P4351-[CERC2015]Frightful Formula【组合数学,MTT】

正题 题目链接:https://www.luogu.com.cn/problem/P4351 题目大意 n∗nn*nn∗n的矩形&#xff0c;给出第一行和第一列的数&#xff0c;剩下的满足Fi,ja∗Fi,j−1b∗Fi−1,jcF_{i,j}a*F_{i,j-1}b*F_{i-1,j}cFi,j​a∗Fi,j−1​b∗Fi−1,j​c 求Fn,nF_{n,n}Fn,n​ 解题思路 第…

阶乘幂与有限微积分

定义 差分算子Δ\DeltaΔ&#xff1a;Δf(x)f(x1)−f(x)\Delta f(x)f(x1)-f(x)Δf(x)f(x1)−f(x)平移算子EEE&#xff1a;Ef(x)f(x1)E f(x)f(x1)Ef(x)f(x1)下降幂&#xff1a;n>0,{xn‾x(x−1)(x−2)...(x−n1)x−n‾1(x1)(x2)(x3)...(xn)n>0,\begin{cases}x^{\underlin…

【Floyd】灾后重建(luogu 1119)

灾后重建 luogu 1119 题目大意 给你一个图&#xff0c;每个点在一定时间后才能被通过&#xff0c;问在某个时间&#xff0c;两个点之间的最短路 输入样例 4 5 1 2 3 4 0 2 1 2 3 1 3 1 2 2 1 4 0 3 5 4 2 0 2 0 1 2 0 1 3 0 1 4输出样例 -1 -1 5 4数据范围 N⩽200&#x…

Ocelot简易教程(三)之主要特性及路由详解

作者&#xff1a;依乐祝原文地址&#xff1a;https://www.cnblogs.com/yilezhu/p/9664977.html上篇《Ocelot简易教程&#xff08;二&#xff09;之快速开始2》教大家如何快速跑起来一个ocelot实例项目&#xff0c;也只是简单的对Ocelot进行了配置&#xff0c;这篇文章会给大家详…

P4245-[模板]任意模数多项式乘法

正题 题目链接:https://www.luogu.com.cn/problem/P4245 题目大意 两个多项式&#xff0c;求它们的乘积模ppp。 解题思路 方法好像挺多&#xff0c;我用的是最简单的一种就是&#xff0c;先定一个常数sqqsqqsqq&#xff08;一般是q\sqrt qq​&#xff09;&#xff0c;把一个…

Poj 3070 Fibonacci

Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 26063 Accepted: 17394文章目录Description题意&#xff1a;题解&#xff1a;代码&#xff1a;Poj 3070 FibonacciDescription In the Fibonacci integer sequence, F0 0, F1 1, and Fn Fn − 1 Fn − 2 for…

生成函数化简技巧

一些重要式子 ∑i0∞xi11−x\sum_{i0}^{\infty}x^i\frac{1}{1-x}∑i0∞​xi1−x1​ 推论&#xff1a; 11−ax∑i0∞aixi\frac{1}{1-ax}\sum_{i0}^{\infty}a^ix^i1−ax1​∑i0∞​aixi 11−xk∑i0∞xik\frac{1}{1-x^k}\sum_{i0}^{\infty}x^{ik}1−xk1​∑i0∞​xik 11−cxk∑i0∞…

.NET西安社区 [拥抱开源,又见 .NET] 活动简报

拥抱开源, 又见 .NET」随着 .NET Core的发布和开源&#xff0c;.NET又重新回到了人们的视野。除了开源、跨平台、高性能以及优秀的语言特性&#xff0c;越来越多的第三方开源库也出现在了Github上——包括ML.NET机器学习、Xamarin移动开发平台、基于Actor模型的分布式框架Orlea…

HDU 2504 又见GCD

HDU 2504 文章目录Problem Description题解&#xff1a;代码&#xff1a;Problem Description 有三个正整数a,b,c(0<a,b,c<10^6)&#xff0c;其中c不等于b。若a和c的最大公约数为b&#xff0c;现已知a和b&#xff0c;求满足条件的最小的c。 Input 第一行输入一个n&#x…