1 Star 0 Fork 11

Jason_Wu / 短信平台

forked from 陈俊波 / 短信平台 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
Apache-2.0

项目分析

一 整体架构

我们是一个分布式的项目,采用Spring Cloud 的方式进行开发,注册中心暂时使用Eureka,各个服务的配置可以保存在配置中心中

二 各个功能

2.1 注册中心

在分布式系统注册中心是一个非常重要的组件,因为所有的服务的地址不确定,数量不确定,所以需要有一个地方来帮我们保存所有的服务器列表

2.1.1 smsplatform-eureka

这个是本项目的注册中心


spring:
  application:
    name: smsplatform-eureka
server:
  port: 10000
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10000/eureka
    fetch-registry: false
    register-with-eureka: false #使用的单机的
    region: 华北  #区域是华北,客户度注册的时候也要加上这个region

2.2 配置中心

我们的项目会分很多个模块,每个模块分很多个机器,一旦配置文件发生变化,需要更新很多个服务器,维护起来非常不方便 我们通过将配置统一保存到某个位置,然后通过某种机制同步即可,我们使用的是config

2.2.1 smsplatform-config

这个是我们项目中统一配置中心的服务端, 配置文件保存在git中,然后通过注册中心进行注册,客户端通过服务发现找到配置中心拉取配置

2020之后的springcloud config客户端需要添加以下单独的依赖包,否则会出错

        

2.3 缓存

我们的项目有大量的地方需要通过缓存来获取数据,所以我们将缓存单独剥离出来作为一个服务,方便修改扩展 缓存也可以作为SDK封装起来给其他的程序导入,但是不方便扩展 我们的缓存使用的是redis来实现的,redis是一个基于KEY-VALUE类型的内存型的非关系型数据库,因为在内存中,速度比较快,处理请求的线程是单线程,没有切换带来的开销,但是处理其他操作的仍然是额外的线程

2.3.1 smsplatform-cache

这个是我们的缓存的模块,然后在内部进行缓存的相关操作 因为redis 的配置会放在配置中心,所以需要bootstrap文件来帮忙加载配置文件

2.3.2 bootstrap.yml
#在当亲文件中进行配置文件的初始化,在线读取配置,因为我们的程序在启动起来进行对象初始化的时候就必须有配置了
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10000/eureka
    region: 华北
spring:
  application:
    name: smsplatform-cache
  cloud:
    inetutils:
      ignored-interfaces: [ 'VMware.*' ] #忽略以Vmware开头的网卡,防止注册服务的时候ip错误导致无法访问
    config:
      discovery:
        enabled: true #开启注册中心的服务发现,也就是从注册中心获取配置中心服务器的相关信息
        service-id: smsplatform-config
      profile: dev #实际查找的文件叫 smsplatform-cache-dev.yml
#  redis:
#    host: 10.9.12.200
#    port: 8400
#    password: redis001
2.3.3 序列化方式

我们的项目中对缓存的操作会保存各种类型的数据, 那么到底以什么统一的格式保存到redis中呢? 我们此处选了key是string,value是json的方式

 @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();

        StringRedisSerializer keySerializer = new StringRedisSerializer();//这是一个string类型的序列化方式
        redisTemplate.setKeySerializer(keySerializer);
        redisTemplate.setHashKeySerializer(keySerializer);

        Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        redisTemplate.setValueSerializer(jsonRedisSerializer);//我们的value到底如何序列化成内容,比如我们以json的方式,就需要一个json类型的序列化
        redisTemplate.setHashValueSerializer(jsonRedisSerializer);

        return redisTemplate;
    }
2.3.4 关于过期时间

我们在操作缓存的时候可能会给某个key单独设置过期时间,过期时间到底能不能是负数 这里取决于我们是否对过期时间的功能进行了扩大化(耦合),比如可以通过过期时间删除指定的key 但是我们一般不会对任何功能进行扩大化处理,因为一旦面临修改可能会出现问题,所以过期时间理论上不能为负数 如果要让一个key过期删掉,可以直接请求删除操作

2.3.5 关于自增的步长

自增的时候正数是增加,负数是减少,步长可以是正数,也可以是负数,但是就是不能为0,因为你自增0就没有任何意义,不应该发起请求 如果期望 通过自增0来拿到当前的值实际上是对自增功能的扩大化,实际上可以直接通过get操作进行获取

2.4 接口模块

当前模块的主要作用是接收客户群体发来的请求,请求的目的是给指定的手机号码发送指定的内容

2.4.1 主要功能
  1. ip过滤

有客户在我们的平台上注册充值了,目的发送短信,结果账号和密码泄露了,有人伪装是这个客户来进行发送短信的操作 我们为了尽量避免出现该情况,所以我们应该做一个处理措施,即便是访问者在知道账号密码的情况下也不能发送短信

  1. 手机号校验

客户传递过来的手机号很有可能不符合规则,虽然客户可能会有前端校验等等措施,但是我们为了保证安全健壮性我们一定要校验 客户可能会传递多个手机号过来,我们需要将多个手机号进行分拆,从一个字符串(数组)转成多个字符串

  1. 账号密码的过滤

我们需要对发送短信的人的信息进行校验,不能随便就允许别人发送短信,需要进行相应校验措施

  1. 短信内容长度

短信的长度是有限制的,不会无限制的长,我们需要对内容进行长度检测,如果超出长度则拆分短信为多条

  1. 状态返回

客户通过我们发送的短信的最终结果到底是成功还是失败, 失败的原因是什么,我们都需要告诉客户,所以这边还有返回结果的操作,但是有些结果并不是实时返回的

2.5 策略模块

策略的作用是通过不同的策略将信息进行相关的操作,比如判断手机号码是不是黑名单,有没有敏感词,有没有钱,有没有限流 包括数据的补全, 省市信息等进行补全 经过上面的分析我们发现策略模块需要做的事情非常多,有多少? 不确定,那么就出现了一个问题,我们到底执行什么策略? 如果增加了一个策略,导致代码发生重大变化怎么办? 最好的方式是不管有什么策略,你增加也好,减少也好,甚至调整顺序也好,我们预先写好的代码不变,只是单纯增加策略类即可 我们想想web中的 filter,我们通过配置文件配置了很多个过滤器, 过滤器就执行了,有个地方一定能从配置文件中读取到所有的配置的过滤器 然后执行里面的方法,执行什么方法?所以过滤器必须实现filter`,就是为了保证不乱传递类型以及可以确定传递过来的对象中一定有某个方法 然后我们就可以写一个类, 在类里面解析xml文件,拿到所有的filter然后遍历执行指定的方法

此处策略暂时使用统一策略机制,也就是所有的用户使用同一个策略分组,后续可以针对不同的用户开启不同的策略分组,比如计费可以按次,包月无限次,包月有限次,包次数不限时间,包次数限时间等不同策略

2.5.1 流程

策略模块会从MQ中获取所有的消息,第一给事情需要先连接MQ,拿到消息后需要经过策略模块的处理,就需要用上面的思路来对消息进行处理

2.5.2 黑名单处理

黑名单怎么处理? 首先要判断是不是在黑名单中? 如何判断? 首先要找到黑名单是如何存档的,存放在什么地方 我们当前的黑名单是通过 BLACK:手机号的方式作为key保存到redis中的,所以我们可以通过 将手机号拼接 BLACK:的方式去查询

如果存储的方式换一个,则判断方式也跟着换, 比如我可以用一个key 将所有的黑名单保存起来到redis的set,然后判断手机号在不在这个set中

方式三, 我们的策略模块在程序启动的时候从redis中同步一份黑名单过来,保存在本地, 后面进行判断的时候从本地判断

2.5.3 敏感词

在内容中不允许出现的内容叫敏感词 如何判断内容中有敏感词, 首先我们得先知道我们的敏感词是什么,然后通过内容的包含关系来判断内容中是否包含指定数据, 字符串的contains()

2.5.4 限流

针对同一个客户向同一个手机号进行发送的次数限制,比如1分钟2次,一小时5次, 一天10次,这个值可以动态变化 当然客户也可以指定自己每天最多发多少条短信,超出后不再发送,此处我们暂时设置统一的限流机制,后续可以增加针对不同客户不同限流机制的措施

如果数据我们保存在redis,首先要确定的是key是什么,当前的策略是每个客户针对某个手机号的, 比如建设银行给13888888888发送的次数不应该影响工商银行给13888888888发送 那么这个key就必须包含 客户信息和手机号信息 比如客户id:手机号 当我们确定了key之后,需要确定value的类型,zset key:value:score 我们以当前发送短信的时间为分数, 去查询指定时间分数范围内的数据长度是不是在限制的范围内,如果不是被限制的 则发送短信,并将当前时间作为分数随便设置一个value 保存到zset

2.5.5 限流的自定义

我们限流的标准, 比如多少次 是可以定义的, 但是时间呢? 比如我们默认1分钟2条, 我们可以将条数自定义,通过查询缓存来获取, 但是我们如果想把限流改成五分钟三次 我们代码中写的时间固定是1 分钟 1小时, 1天,说明代码中的时间也不能直接写死, 而是可以通过某种方式获取 比如我们保存到zset, 以某个固定值如limitparam作为key, 以限流的时间作为 score,以次数作为值保存起来 这样我们可以通过查询这个zset获取到所有的限流的时间和次数 ,比如我们保存了一个 300 3 意味着是5分钟内限制3次 而且因为时间的天然顺序原因,我们的不同的限流措施还可以排序,比如 5分钟的和2小时的在这个zset中顺序可以排序

2.5.6 号段补全

在产品的需求中,我们可能会对目标手机号的区域进行一些操作,比如说我们经过统计发现,这个发送的短信号码中,有三分之一发送到了北京,那我们可以去和北京的运营商谈合作,市内短信相对比较便宜,所以可以多加几个对应地区的合作商 那么问题来了,在什么地方能找到手机号属于什么地区(既然需要统计,就需要保存数据,数据在哪里保存了),我们在短信的内容对象中设置了两个属性,一个是省id,一个是市id,我们只需要给这两个数据设置值即可 在我们的缓存中,我们给每个号段设置了一个key,value是对应的省市id,我们可以根据手机号的前7位来获取这个数据

2.5.7 搜索

在我们的搜索功能中,遇到了一个问题,我们传递的搜索的条件个数和类型不一定, 可能会有某个类型的参数,可能没有,并且后续可能会添加参数个数以及类型 我们期望写一个方法,这个方法和参数的个数以及类型无关,也就是理论上不论怎么传递参数都可以实现查询

2.5.7.1 设计思路

用户可以传递的参数虽然是变化的, 但是仍然是我们服务端定义好的,所以我们可以先设计一个模板,里面定义每个参数的名字以及查询的类型 用户在传递了参数过来后,我们先去匹配一下是什么类型的查询,然后才去拼接查询条件 比如: name:"phonenum",type:"term" 代表有一个参数叫phonenum 是term类型 name:"content",type:"match" 代表有一个参数叫content 是match类型 name:"starttime",type:"date",cloum :"sendate",guanlian:"stoptime",order:0 有一个参数叫starttime 是日期类型,是sendate条件的起点时间,关联的终点参数是stoptime name:"stoptime",type:"date",cloum :"sendate",guanlian:"starttime",order:1

2.5.8 定时任务

定时任务的主要作用是在特定的时间做一些事情,比如我们的闹钟,我们用过quartz实现的定时任务 但是定时任务会遇到问题, 定时任务所在的程序理论上是独立的,那么就会出现单点故障问题,定时任务需要集群 如果是集群,就意味着每个机器上面都有一模一样的任务,那任务就重复执行了,也不行 所以我们需要一种技术,1 一定是集群,2 在集群的情况下仍然只有一个机器在执行任务,如果执行任务的机器坏了,最好能自动漂移到其他机器 我有很多个机器在执行任务,但是最终只有一个机器执行,其他机器都浪费了,万一长时间都没有损坏的机器,就会出现其他机器全部浪费的情况 比如我要是执行一个大点的耗时任务,要是这些机器能都参与进来即好了

异常

  1. 提供者返回void 但是消费者的openfeign有返回值类型的时候会导致控指针
  2. ES中进行高亮搜索的时候,高亮的标签使用 这种格式的时候 = 两边要么全部都有空格,要么都没有,否则会出现操作超时的异常 但是通过style="color:red" 的方式没有问题
Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

简介

短信平台代码 展开 收起
Apache-2.0
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/june-woo/sms-platform.git
git@gitee.com:june-woo/sms-platform.git
june-woo
sms-platform
短信平台
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891