搭建亿万级别短信服务发送平台

本文涉及的产品
短信服务,100条 3个月
短信服务,200条 3个月
国际/港澳台短信套餐包,全球plus 100条 6个月
简介: 阿里云的小伙伴们,走过路过,千万不要错过。之所以起这么唬人的标题,其实就是想让路过的您点一下,顺便关注一下博主。当然你也可以默默地顶完文章然后转身就走人,但是动作一定要快,姿势必须要帅,深藏功名尘与土。

写在开始

阿里云的小伙伴们,走过路过,千万不要错过。之所以起这么唬人的标题,其实就是想让路过的您点一下,顺便关注一下博主。当然你也可以默默地顶完文章然后转身就走人,但是动作一定要快,姿势必须要帅,深藏功名尘与土。

700615905

阿里大鱼

阿里大鱼去哪了,这么牛掰的名字,居然被阿里云抛弃了?

显然不是,进入短信后台。阿里云还是给了提示:原短信服务已停止开通。
感谢你对短信服务产品的支持,原短信服务(整合在消息服务内)已停止开通。请前往短信服务控制台,开通新短信服务。

很明显短信服务被整合到消息服务中去了,阿里大鱼也不能单独存在了。

让我们先默哀三分钟~~~
3

短信接入

产品介绍

消息服务同时具备发送短信的能力,支持快速发送短信验证码、短信通知、推广短信。完美支撑双11期间的2亿用户发送6亿条短信。三网合一专属通道,与工信部携号转网平台实时互联。电信级运维保证,实时监控自动切换,到达率高达99%。

  • 短信通知和验证码:大容量高并发,支撑双11期间2亿用户发送6亿短信。3秒可达,三网合一专属通道。变量灵活,支持带入变量,内容灵活,可适应支持各业务场景。
  • 推广短信:支持多种推广内容的短信发放,为提升企业产品增加曝光率提供帮助。业务推广、新产品宣讲、会员关怀等进行短信发送。
  • 批量发送:一对多广播消息,发布到主题中的一条消息可以同时被多个订阅者订阅,会被按照多个订阅指定的推送方式和 Endpoint 地址推送过去。
  • 异步通知:可以后端服务处理完成任务时,回调通知用户。进而减少用户,Web前端和后端服务之间大量不必要的轮询请求。
  • 数据统计:可查看请求量、发送成功量、失败量、等统计数据;通过日期、手机号等维度,查看发送详情;

短信接入完整流程:
sms

消息服务开通地址
https://www.aliyun.com/product/mns

开通短信服务,默认是会送10元代金券的(便于我们开发人员测试使用)。测试成功以后,你也可以购买短信服务资源包(这个是比较坑的,购买时长居然只有一个月?是否说明,买多少这个月我都得必须用完?)

由于博主是个JAVA开发者,然果断选择了JAVA的SDK,当然开发短信服务之前,你还需要做以下操作。

短信签名

签名类型:由于是个人用户,只能 选择验证码或短信通知(0.045元/条)
签名:比如我的是网站,所以填写科帮网
签名用途:个人使用,签名为自己产品名/网站名等
申请说明:非必填,最好填写申请理由

1

短信模版

模版类型:验证码和短信通知(根据业务情况选择 )
模版名称:自定义即可
模版内容: 标准规范https://help.aliyun.com/document_detail/55324.html
申请说明:请描述您的业务使用场景

2

签名和模版一般2小时内审核完成(上班时间其实还是很快的),审核通过后就可以接入使用了。

短信接入

使用工具:Eclipse、Maven、SendSms(SDK)、JDK1.7、阿里云的访问密钥

秘钥管理地址:https://ak-console.aliyun.com/
SDK下载地址:https://help.aliyun.com/document_detail/55359.html

阿里开发人员写的代码和文档这里就不做过多评论了,意见和建议只能促进大家进步,没什么其他的意思。可以参考这篇帖子:https://bbs.aliyun.com/read/317490.html

一个211理工科硕士的表白(阿里短信工程师你们听到了没有?)

项目接入

首先,展示下劳动成果,控制台发送成功提示:

4

配置Maven

按照文档果然不靠谱,下载下来的文件太多,以至于有点懵比。其实单就发送短信来说,只需要以下两个JAR包aliyun-java-sdk-core-3.2.2.jar和aliyun-java-sdk-dysmsapi-1.0.0.jar(自行打入maven仓库或者本地私服)。

但是,阿里云开发人员给的文档又是怎么说的呢?SDK工具包中一共包含了2个类库,一个aliyun-java-sdk-core包,另外一个是alicom-dysms-api包。

对比一下,我觉得我是猜对的。如果我理解的没有错误,建立开发人员还是要认真一点。

除了阿里的SDk,额外还引入了log4j和gson相关jar包,用于记录日志和组织JSON数据,以下是依赖:

<dependencies>
        <!-- 版本自定义即可-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>sdk-dysmsapi</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>sdk-core</artifactId>
            <version>3.2.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.3.1</version>
        </dependency>
    </dependencies>

AliSmsConfig:
IAcsClient单例实现,所有的参数都在这个类中配置。

package com.alicom.dysms.config;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
/**
 * 单例实现
 * 创建者 科帮网
 * 创建时间    2017年6月29日
 *
 */
public class AliSmsConfig {
    private AliSmsConfig(){};
    static final String signName = "科帮网";//签名
    static final String templateCode = "SMS_110";//模版
    static final String product = "Dysmsapi";
    static final String domain = "dysmsapi.aliyuncs.com";
    static final String accessKeyId = "XXX";//此处私钥 填写自己的
    static final String accessKeySecret = "XXX";//此处私钥 填写自己的
    static final IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
    static {
        try {
            System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
            System.setProperty("sun.net.client.defaultReadTimeout", "10000");
            DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
        } catch (ClientException e) {
            e.printStackTrace();
        }
    }
    /**
     * 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例
     * 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载
     */
    private static class SingletonHolder{
        /**
         * 静态初始化器,由JVM来保证线程安全
         */
        private  static  IAcsClient acsClient = new DefaultAcsClient(profile);
    }
    public static IAcsClient getAcsClient(){
        return SingletonHolder.acsClient;
    }
}

SmsUtil:

package com.alicom.dysms.config;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
/**
 * 短信发送工具类
 * 创建者 科帮网
 * 创建时间    2017年6月29日
 *
 */
public class SmsUtil {
    private static final Logger LOG = LogManager.getLogger(SmsUtil.class.getName());
    public static SendSmsResponse sendSms(SendSmsRequest request) {
        SendSmsResponse sendSmsResponse = null;
        LOG.info("发送手机验证码:"+request.getPhoneNumbers());
        try {
            IAcsClient acsClient = AliSmsConfig.getAcsClient();
            //必填:短信签名-可在短信控制台中找到
            request.setSignName(AliSmsConfig.signName);
            //必填:短信模板-可在短信控制台中找到
            request.setTemplateCode(AliSmsConfig.templateCode);
            sendSmsResponse = acsClient.getAcsResponse(request);
        } catch (Exception e) {
            LOG.error("短信发送异常:"+request.getPhoneNumbers(), e);
        }
        return sendSmsResponse;
    }
}

SmsDemo:

package com.alicom.dysms.web;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import com.alicom.dysms.config.SmsUtil;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.google.gson.JsonObject;
/**
 * 阿里短信发送Demo
 * 创建者 科帮网
 * 创建时间    2017年6月29日
 *
 */
public class SmsDemo {
    private static final Logger LOG = LogManager.getLogger(SmsDemo.class.getName());
    public static void main(String[] args) throws ClientException, InterruptedException {
        SendSmsRequest request = new SendSmsRequest();
        //必填:待发送手机号
        request.setPhoneNumbers("18866668888");
        //尊敬的${name},您正进行科帮网的身份验证,验证码${number},打死不告诉别人!
        JsonObject params = new JsonObject();
        params.addProperty("name", "小柒");
        params.addProperty("number", "111111");
        request.setTemplateParam(params.toString());
        SendSmsResponse response = SmsUtil.sendSms(request);
        LOG.info("--------短信接口返回的数据--------");
        if("OK".equals(response.getCode())){
            System.out.println("Code=" + response.getCode());
            System.out.println("Message=" + response.getMessage());
            System.out.println("RequestId=" + response.getRequestId());
            System.out.println("BizId=" + response.getBizId());
            LOG.info("短信发送成功");
        }
    }
}

SendServlet:
当然,由于没有使用任何web框架,这里还写了一个Servlet的Demo,仅供参考。

package com.alicom.dysms.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alicom.dysms.config.SmsUtil;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.google.gson.JsonObject;
/**
 * 短信发送
 * 创建者 科帮网
 * 创建时间    2017年6月29日
 */
public class SendServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doPost(request, response);
    }
    
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String mobile = request.getParameter("mobile");//手机
        String number = request.getParameter("number");//验证码
        SendSmsRequest sms = new SendSmsRequest();
        sms.setPhoneNumbers(mobile);
        JsonObject params = new JsonObject();
        params.addProperty("name", "小柒");
        params.addProperty("number", number);
        sms.setTemplateParam(params.toString());
        SendSmsResponse res = SmsUtil.sendSms(sms);
        PrintWriter out = response.getWriter();
        if("OK".equals(res.getCode())){
            out.print("success");
        }else{
            out.print("fail");
        }
    }
}

web.xml:

<web-app>
  <display-name>aliyun_sms</display-name>
  <servlet>
        <servlet-name>SendServlet</servlet-name>
        <servlet-class>com.alicom.dysms.servlet.SendServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>SendServlet</servlet-name>
        <url-pattern>/SendServlet</url-pattern>
    </servlet-mapping>
</web-app>

接入必读

  • 很多用户反映变量中输入了非数字发送失败?
    由于现阶段国家管控严格,目前只能发送验证码类型短信,变量只支持验证码且验证码为6位以内的数字。您需要创建一个仅包含验证码变量的短信模板,还烦请您进行调整。
  • 也有用户反应明明发送了一条短信,统计显示发送了两条,神马鬼?
    短信字数=短信模板内容字数 + 签名字数

短信字数<=70个字数,按照70个字数一条短信计算
短信字数>70个字数,即为长短信,按照67个字数记为一条短信计算
至于为什么这么算,就要问电信运行商了,上世纪遗留问题

  • 至于,论坛一些用户反映看不懂文档?
    建议大鱼要么不做,放出来就要做好,作为开发人员都知道看别人写的代码是多么~,况且文档,代码描述的还不是特别清楚。

当然,更多问题建议大家参考:https://help.aliyun.com/document_detail/55288.html

最后的最后,标题的确是有点彪。写了个定时任务,7天以后标题会自动修改为《如何接入亿万级别短信服务发送平台》。

欢迎关注小站:https://blog.52itstyle.com/ 获取更多信息

代码:https://git.oschina.net/52itstyle/aliyun_sms

目录
相关文章
阿里云短信服务平台价格表
阿里云短信服务平台价格表,阿里云短信服务价格表,阿里云短信0.032元一条,阿里云短信价格?阿里云短信怎么收费?阿里云短信多少钱一条,阿里云短信价格0.032元一条
340 0
|
NoSQL Java Redis
java使用阿里云短信服务发送短信验证码
java使用阿里云短信服务发送短信验证码
912 0
|
6月前
|
云安全 安全 API
阿里云——OpenAPI使用——短信服务
阿里云——OpenAPI使用——短信服务
318 0
|
11月前
|
安全
阿里云短信服务是可以发送包含下载链接的文本内容的,
阿里云短信服务是可以发送包含下载链接的文本内容的,但是需要注意以下几点:
664 1
|
SQL Java
如何使用阿里云短信服务实现登录页面,手机验证码登录?1
如何使用阿里云短信服务实现登录页面,手机验证码登录?
415 0
|
1月前
|
API
阿里云短信服务文档与实际API不符
阿里云短信服务文档与实际API不符
|
2月前
|
数据采集 监控 安全
阿里云短信服务+图形认证,有效降低验证码盗刷概率
阿里云短信服务+图形认证服务,有效降低验证码盗刷概率。
258 3
阿里云短信服务+图形认证,有效降低验证码盗刷概率
|
20天前
|
安全 Java API
【三方服务集成】最新版 | 阿里云短信服务SMS使用教程(包含支持单双参数模板的工具类,拿来即用!)
阿里云短信服务提供API/SDK和控制台调用方式,支持验证码、通知、推广等短信类型。需先注册阿里云账号并实名认证,然后在短信服务控制台申请资质、签名和模板,并创建AccessKey。最后通过Maven引入依赖,使用工具类发送短信验证码。
【三方服务集成】最新版 | 阿里云短信服务SMS使用教程(包含支持单双参数模板的工具类,拿来即用!)
|
3月前
|
数据采集 存储 监控
99%成功率背后:阿里云短信服务有何优势?
为什么短信会发送失败,如何提高短信发送成功率,本文将为您介绍短信发送成功率和阿里云短信服务如何保障企业短信稳定送达等相关知识。
200 1
99%成功率背后:阿里云短信服务有何优势?
|
6月前
|
JSON 开发工具 数据格式
App Inventor 2 接入阿里云短信服务,实现短信验证码功能
App Inventor 2 接入阿里云短信服务,实现短信验证码功能:发送短信验证码功能一般都是基于短信平台提供的sdk进行调用,这里是基于阿里云短信平台进行的开发。
218 1
下一篇
无影云桌面