微信公众平调试开发部署实战(Java)
时间:2023-05-28 12:09:01 | 来源:网站运营
时间:2023-05-28 12:09:01 来源:网站运营
微信公众平调试开发部署实战(Java):
内容介绍:微信公众平台、Java开发环境搭建、多站点Nginx反向代理、内网隧道穿透NAT、任务型对话系统、图灵机器人、开发者微信公众消息体结构。
微信公众平台的口号是:再小的个体,也有自己的品牌。微信公众平台实现了信息通知、用户连接和用户管理的功能,可以与用户互动起来。
微信公众号已经成为了一个人找信息、信息找人、信息找信息、人找人的多向交流工具,毫无疑问微信公众号在为用户提供有价值的内容信息、进行客户管理、提高用户粘性等都发挥了巨大价值。而且微信公众号、小程序、视频号、微信支付等形成了闭环,他们之间进行了互通,也为用户提供了非常好的体验。
微信公众平台是运营者通过公众号为微信用户提供资讯和服务的平台,而公众平台开放接口则是提供服务的基础。微信公众号平台提供了基础的如自定义菜单,消息回复等功能。想要定制化为用户提供服务还是需要搭建自己的微信公众号服务器来为用户提供服务,而这块儿是需要编码部署,域名申请备案等。大部分微信公众号博主只能借助第三方,成本也是比较高;本次分享也是希望能对大家有所帮助。
对于微信公众号平台开发者一般都是在局域网进行开发,那么和外网是不互通的,所以能有免费的内网穿透工具还提供域名以及域名解析方案肯定能使得开发效率大大提高。
1 公众号功能介绍
为了识别用户,每个用户针对每个公众号会产生一个安全的OpenID,如果需要在多公众号、移动应用之间做用户共通,则需前往微信开放平台,将这些公众号和应用绑定到一个开放平台账号下,绑定后,一个用户虽然对多个公众号和应用有多个不同的OpenID,但他对所有这些同一开放平台账号下的公众号和应用,只有一个UnionID,可以在用户管理 - 获取用户基本信息(UnionID机制)文档了解详情。
1、微信公众平台开发是指为微信公众号进行业务开发,为移动应用、PC端网站、公众号第三方平台(为各行各业公众号运营者提供服务)的开发,请前往微信开放平台接入。
2、在申请到认证公众号之前,你可以先通过测试号申请系统,快速申请一个接口测试号,立即开始接口测试开发。
3、在开发过程中,可以使用接口调试工具来在线调试某些接口。
4、每个接口都有每日接口调用频次限制,可以在公众平台官网 - 开发者中心处查看具体频次。
5、在开发出现问题时,可以通过接口调用的返回码,以及报警排查指引(在公众平台官网 - 开发者中心处可以设置接口报警),来发现和解决问题。
6、公众平台以access_token为接口调用凭据,来调用接口,所有接口的调用需要先获取access_token,access_token在2小时内有效,过期需要重新获取,但1天内获取次数有限,开发者需自行存储,详见获取接口调用凭据(access_token)文档。
公众号主要通过公众号消息会话和公众号内网页来为用户提供服务的,下面分别介绍这两种情况:
1、公众号消息会话公众号是以微信用户的一个联系人形式存在的,消息会话是公众号与用户交互的基础。目前公众号内主要有这样几类消息服务的类型,分别用于不同的场景。
1)群发消息:公众号可以以一定频次(订阅号为每天1次,服务号为每月4次),向用户群发消息,包括文字消息、图文消息、图片、视频、语音等。
2)被动回复消息:在用户给公众号发消息后,微信服务器会将消息发到开发者预先在开发者中心设置的服务器地址(开发者需要进行消息真实性验证),公众号可以在5秒内做出回复,可以回复一个消息,也可以回复命令告诉微信服务器这条消息暂不回复。被动回复消息可以设置加密(在公众平台官网的开发者中心处设置,设置后,按照消息加解密文档来进行处理。其他3种消息的调用因为是 API 调用而不是对请求的返回,所以不需要加解密)。
3)客服消息:用户在公众号内发消息/触发特定行为后,公众号可以给用户发消息。具体发送规则见公众号客服消息文档:
https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Service_Center_messages.html。
4)模板消息:在需要对用户发送服务通知(如刷卡提醒、服务预约成功通知等)时,公众号可以用特定内容模板,主动向用户发送消息。
2、公众号内网页许多复杂的业务场景,需要通过网页形式来提供服务,这时需要用到:
1)网页授权获取用户基本信息:通过该接口,可以获取用户的基本信息(获取用户的 OpenID 是无需用户同意的,获取用户的基本信息则需用户同意)
2)微信JS-SDK:是开发者在网页上通过 JavaScript 代码使用微信原生功能的工具包,开发者可以使用它在网页上录制和播放微信语音、监听微信分享、上传手机本地图片、拍照等许多能力。
1.1 类型介绍
图1 类型介绍微信开放文档
不同的公众号类型具备不同的接口权限,具体如下表: 请注意:
- 微博认证视作未认证,因此微博认证的公众号不会拥有微信认证公众号特有的接口。
- 微信认证分为资质认证和名称认证两部分,只需要资质认证通过,就可获得接口。
接口名称 | 未认证订阅号 | 微信认证订阅号 | 未认证服务号 | 微信认证服务号 |
---|
基础支持 - 获取access_token | 有 | 有 | 有 | 有 |
基础支持 - 获取微信服务器 IP 地址 | 有 | 有 | 有 | 有 |
接收消息 - 验证消息真实性、接收普通消息、接收事件推送、接收语音识别结果 | 有 | 有 | 有 | 有 |
发送消息 - 被动回复消息 | 有 | 有 | 有 | 有 |
发送消息 - 客服接口 | | 有 | | 有 |
发送消息 - 群发接口 | | 有 | | 有 |
发送消息 - 模板消息接口(发送业务通知) | | | | 有 |
发送消息 - 一次性订阅消息接口 | | 有 | | 有 |
用户管理 - 用户分组管理 | | 有 | | 有 |
用户管理 - 设置用户备注名 | | 有 | | 有 |
用户管理 - 获取用户基本信息 | | 有 | | 有 |
用户管理 - 获取用户列表 | | 有 | | 有 |
用户管理 - 获取用户地理位置 | | | | 有 |
用户管理 - 网页授权获取用户openid/用户基本信息 | | | | 有 |
推广支持 - 生成带参数二维码 | | | | 有 |
推广支持 - 长链接转短链接口 | | | | 有 |
界面丰富 - 自定义菜单 | | 有 | 有 | 有 |
素材管理 - 素材管理接口 | | 有 | | 有 |
智能接口 - 语义理解接口 | | | | 有 |
多客服 - 获取多客服消息记录、客服管理 | | | | 有 |
微信支付接口 | | | | 需申请 |
微信小店接口 | | | | 需申请 |
微信卡券接口 | | 需申请 | | 需申请 |
微信设备功能接口 | | | | 需申请 |
微信发票接口 | | 有 | | 有 |
微信 JS-SDK- 基础接口 | 有 | 有 | 有 | 有 |
微信 JS-SDK- 分享接口 | | 有 | | 有 |
微信 JS-SDK- 图像接口 | 有 | 有 | 有 | 有 |
微信 JS-SDK- 音频接口 | 有 | 有 | 有 | 有 |
微信 JS-SDK- 智能接口(网页语音识别) | 有 | 有 | 有 | 有 |
微信 JS-SDK- 设备信息 | 有 | 有 | 有 | 有 |
微信 JS-SDK- 地理位置 | 有 | 有 | 有 | 有 |
微信 JS-SDK- 界面操作 | 有 | 有 | 有 | 有 |
微信 JS-SDK- 微信扫一扫 | 有 | 有 | 有 | 有 |
微信 JS-SDK- 微信小店 | | | | 有 |
微信 JS-SDK- 微信卡券 | | 有 | | 有 |
微信 JS-SDK- 微信支付 | | | | 有 |
1.2 公众号申请
微信注册申请:微信公众平台
图2 微信公众号注册图3 官方平台 官方文档:微信公众平台开发概述 | 微信开放文档
图4 微信公众号官方文档1.3 编辑模式和开发者模式
编辑模式:编辑模式指所有的公众号运营者都可以通过简单的编辑,设置“按关键字回复”等功能。您可以设定常用的文字/语言/图片/录音作为回复消息,并制定自动回复的规则。当订阅用户的行为符合自动回复规则的时候,就会收到自动回复的消息。
开发模式:开发模式是为开发者提供与用户进行消息交互的能力。对于成功接入消息接口的公众账号,当用户发消息给公众号,微信公众平台服务器会使用http请求对接入的网址进行消息推送,第三方服务器可通过响应包回复特定结构,从而达到回复消息的目的。
微信公众平台编辑模式和开发模式互相切换后对原保存在内容不会做更改的,原来保存的内容是不会丢失的。
1.4 消息回复例子(编辑模式)
图5 公众号消息回复 编辑模式1.5 自定义菜单例子(编辑模式)
图6 自定义菜单 编辑模式1.6 开发者模式接入指南
接入概述 | 微信开放文档
接入微信公众平台开发,开发者需要按照如下步骤完成:
1、填写服务器配置
2、验证服务器地址的有效性
3、依据接口文档实现业务逻辑
下面详细介绍这3个步骤。(如你已有小程序,并且已开通小程序云开发,也可以使用 公众号环境共享 能力,在公众号中使用云开发。)
步骤一、填写服务器配置 登录微信公众平台官网后,在公众平台官网的开发 - 基本设置页面,勾选协议成为开发者,点击“修改配置”按钮,填写服务器地址(URL)、Token和EncodingAESKey,其中 URL 是开发者用来接收微信消息和事件的接口URL。Token可由开发者可以任意填写,用作生成签名(该 Token 会和接口 URL 中包含的 Token 进行比对,从而验证安全性)。EncodingAESKey由开发者手动填写或随机生成,将用作消息体加解密密钥。
图7 公众号服务器配置步骤二、验证服务器地址的有效性开发者提交信息后,微信服务器将发送 GET 请求到填写的服务器地址 URL 上,GET请求携带参数如下表所示:
参数 | 描述 |
---|
signature | 微信加密签名,signature结合了开发者填写的 token 参数和请求中的 timestamp 参数、nonce参数。 |
timestamp | 时间戳 |
nonce | 随机数 |
echostr | 随机字符串 |
开发者通过检验 signature 对请求进行校验(下面有校验方式)。若确认此次 GET 请求来自微信服务器,请原样返回 echostr 参数内容,则接入生效,成为开发者成功,否则接入失败。加密/校验流程如下:
1)将token、timestamp、nonce三个参数进行字典序排序 2)将三个参数字符串拼接成一个字符串进行sha1加密 3)开发者获得加密后的字符串可与 signature 对比,标识该请求来源于微信
检验 signature 的JAVA示例代码:
String result = ""; /** 判断是否是微信接入激活验证,只有首次接入验证时才会收到echostr参数,此时需要把它直接返回 */ // 随机字符串 String echostr = request.getParameter("echostr"); if (echostr != null && echostr.length() > 1) { String signature = request.getParameter("signature");// 微信加密签名 String timestamp = request.getParameter("timestamp");// 时间戳 String nonce = request.getParameter("nonce");// 随机数 String checkSignature = WeChatUtil.checkSignature(timestamp,nonce); if (signature.equals(checkSignature)) { result = echostr; //请求验证成功,返回随机码 } else { result = ""; } } else { //正常的微信处理流程 if (!xml.equals("")) result = new WechatProcess().processWechatMag(xml); }
public static String checkSignature(String timestamp,String nonce){ // 重写toString方法,得到三个参数的拼接字符串 List<String> list = new ArrayList<String>(3) { private static final long serialVersionUID = 2621444383666420433L; public String toString() { return this.get(0) + this.get(1) + this.get(2); } }; list.add(Utils.TOKEN); list.add(timestamp); list.add(nonce); Collections.sort(list);// 排序 String newSignature = new MySecurity().encode(list.toString(), MySecurity.SHA_1);// SHA-1加密 return newSignature; }
步骤三、依据接口文档实现业务逻辑根据官方文档接口开发实现自己的业务逻辑,比如我们会使用对接图灵机器人实现智能助手功能
1.7 微信平台交互消息体接口
文本消息 | 微信开放文档
当普通微信用户向公众账号发消息时,微信服务器将 POST 消息的 XML 数据包到开发者填写的 URL 上。
- 关于重试的消息排重,推荐使用 msgid 排重。
- 微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。详情请见“发送消息 - 被动回复消息”。
- 如果开发者需要对用户消息在5秒内立即做出回应,即使用“发送消息 - 被动回复消息”接口向用户被动回复消息时,可以在公众平台官网的开发者中心处设置消息加密。开启加密后,用户发来的消息和开发者回复的消息都会被加密(但开发者通过客服接口等 API 调用形式向用户发送消息,则不受影响)。
各消息类型的推送 XML 数据包结构如下:普通文本消息<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1348831860</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[this is a test]]></Content> <MsgId>1234567890123456</MsgId> <MsgDataId>xxxx</MsgDataId> <Idx>xxxx</Idx></xml>
参数 | 描述 |
---|
ToUserName | 开发者微信号 |
FromUserName | 发送方帐号(一个OpenID) |
CreateTime | 消息创建时间 (整型) |
MsgType | 消息类型,文本为text |
Content | 文本消息内容 |
MsgId | 消息id,64位整型 |
MsgDataId | 消息的数据ID(消息如果来自文章时才有) |
Idx | 多图文时第几篇文章,从1开始(消息如果来自文章时才有) |
使用网页调试工具调试该接口
图片消息<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1348831860</CreateTime> <MsgType><![CDATA[image]]></MsgType> <PicUrl><![CDATA[this is a url]]></PicUrl> <MediaId><![CDATA[media_id]]></MediaId> <MsgId>1234567890123456</MsgId> <MsgDataId>xxxx</MsgDataId> <Idx>xxxx</Idx></xml>
参数 | 描述 |
---|
ToUserName | 开发者微信号 |
FromUserName | 发送方帐号(一个OpenID) |
CreateTime | 消息创建时间 (整型) |
MsgType | 消息类型,图片为image |
PicUrl | 图片链接(由系统生成) |
MediaId | 图片消息媒体id,可以调用获取临时素材接口拉取数据。 |
MsgId | 消息id,64位整型 |
MsgDataId | 消息的数据ID(消息如果来自文章时才有) |
Idx | 多图文时第几篇文章,从1开始(消息如果来自文章时才有) |
使用网页调试工具调试该接口
语音消息<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1357290913</CreateTime> <MsgType><![CDATA[voice]]></MsgType> <MediaId><![CDATA[media_id]]></MediaId> <Format><![CDATA[Format]]></Format> <MsgId>1234567890123456</MsgId> <MsgDataId>xxxx</MsgDataId> <Idx>xxxx</Idx></xml>
参数 | 描述 |
---|
ToUserName | 开发者微信号 |
FromUserName | 发送方帐号(一个OpenID) |
CreateTime | 消息创建时间 (整型) |
MsgType | 语音为voice |
MediaId | 语音消息媒体id,可以调用获取临时素材接口拉取数据。 |
Format | 语音格式,如amr,speex等 |
MsgId | 消息id,64位整型 |
MsgDataId | 消息的数据ID(消息如果来自文章时才有) |
Idx | 多图文时第几篇文章,从1开始(消息如果来自文章时才有) |
使用网页调试工具调试该接口
请注意,开通语音识别后,用户每次发送语音给公众号时,微信会在推送的语音消息 XML 数据包中,增加一个 Recognition 字段(注:由于客户端缓存,开发者开启或者关闭语音识别功能,对新关注者立刻生效,对已关注用户需要24小时生效。开发者可以重新关注此帐号进行测试)。开启语音识别后的语音 XML 数据包如下:
<xml> <ToUserName>< ![CDATA[toUser] ]></ToUserName> <FromUserName>< ![CDATA[fromUser] ]></FromUserName> <CreateTime>1357290913</CreateTime> <MsgType>< ![CDATA[voice] ]></MsgType> <MediaId>< ![CDATA[media_id] ]></MediaId> <Format>< ![CDATA[Format] ]></Format> <Recognition>< ![CDATA[腾讯微信团队] ]></Recognition> <MsgId>1234567890123456</MsgId> <MsgDataId>xxxx</MsgDataId> <Idx>xxxx</Idx></xml>
参数说明:
参数 | 描述 |
---|
ToUserName | 开发者微信号 |
FromUserName | 发送方帐号(一个OpenID) |
CreateTime | 消息创建时间 (整型) |
MsgType | 语音为voice |
MediaId | 语音消息媒体id,可以调用获取临时素材接口拉取该媒体 |
Format | 语音格式:amr |
Recognition | 语音识别结果,UTF8编码 |
MsgId | 消息id,64位整型 |
MsgDataId | 消息的数据ID(消息如果来自文章时才有) |
Idx | 多图文时第几篇文章,从1开始(消息如果来自文章时才有) |
视频消息<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1357290913</CreateTime> <MsgType><![CDATA[video]]></MsgType> <MediaId><![CDATA[media_id]]></MediaId> <ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId> <MsgId>1234567890123456</MsgId> <MsgDataId>xxxx</MsgDataId> <Idx>xxxx</Idx></xml>
参数 | 描述 |
---|
ToUserName | 开发者微信号 |
FromUserName | 发送方帐号(一个OpenID) |
CreateTime | 消息创建时间 (整型) |
MsgType | 视频为video |
MediaId | 视频消息媒体id,可以调用获取临时素材接口拉取数据。 |
ThumbMediaId | 视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。 |
MsgId | 消息id,64位整型 |
MsgDataId | 消息的数据ID(消息如果来自文章时才有) |
Idx | 多图文时第几篇文章,从1开始(消息如果来自文章时才有) |
使用网页调试工具调试该接口
小视频消息<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1357290913</CreateTime> <MsgType><![CDATA[shortvideo]]></MsgType> <MediaId><![CDATA[media_id]]></MediaId> <ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId> <MsgId>1234567890123456</MsgId> <MsgDataId>xxxx</MsgDataId> <Idx>xxxx</Idx></xml>
参数 | 描述 |
---|
ToUserName | 开发者微信号 |
FromUserName | 发送方帐号(一个OpenID) |
CreateTime | 消息创建时间 (整型) |
MsgType | 小视频为shortvideo |
MediaId | 视频消息媒体id,可以调用获取临时素材接口拉取数据。 |
ThumbMediaId | 视频消息缩略图的媒体id,可以调用获取临时素材接口拉取数据。 |
MsgId | 消息id,64位整型 |
MsgDataId | 消息的数据ID(消息如果来自文章时才有) |
Idx | 多图文时第几篇文章,从1开始(消息如果来自文章时才有) |
使用网页调试工具调试该接口
地理位置消息<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1351776360</CreateTime> <MsgType><![CDATA[location]]></MsgType> <Location_X>23.134521</Location_X> <Location_Y>113.358803</Location_Y> <Scale>20</Scale> <Label><![CDATA[位置信息]]></Label> <MsgId>1234567890123456</MsgId> <MsgDataId>xxxx</MsgDataId> <Idx>xxxx</Idx></xml>
参数 | 描述 |
---|
ToUserName | 开发者微信号 |
FromUserName | 发送方帐号(一个OpenID) |
CreateTime | 消息创建时间 (整型) |
MsgType | 消息类型,地理位置为location |
Location_X | 地理位置纬度 |
Location_Y | 地理位置经度 |
Scale | 地图缩放大小 |
Label | 地理位置信息 |
MsgId | 消息id,64位整型 |
MsgDataId | 消息的数据ID(消息如果来自文章时才有) |
Idx | 多图文时第几篇文章,从1开始(消息如果来自文章时才有) |
使用网页调试工具调试该接口
链接消息<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1351776360</CreateTime> <MsgType><![CDATA[link]]></MsgType> <Title><![CDATA[公众平台官网链接]]></Title> <Description><![CDATA[公众平台官网链接]]></Description> <Url><![CDATA[url]]></Url> <MsgId>1234567890123456</MsgId> <MsgDataId>xxxx</MsgDataId> <Idx>xxxx</Idx></xml>
参数 | 描述 |
---|
ToUserName | 接收方微信号 |
FromUserName | 发送方微信号,若为普通用户,则是一个OpenID |
CreateTime | 消息创建时间 |
MsgType | 消息类型,链接为link |
Title | 消息标题 |
Description | 消息描述 |
Url | 消息链接 |
MsgId | 消息id,64位整型 |
MsgDataId | 消息的数据ID(消息如果来自文章时才有) |
Idx | 多图文时第几篇文章,从1开始(消息如果来自文章时才有) |
更多功能请查阅官方文档:文本消息 | 微信开放文档
关注/取消关注事件 | 微信开放文档
创建个性化菜单 | 微信开放文档
2 内网穿透技术
2.1 介绍
内网穿透,又称为NAT穿透,简单来说就是将内网外网通过穿透隧道打通,让内网的数据让外网可以获取。
NAT背后的设备,它们的主要特点是 ,可以访问外网,但不能被外网设备有效访问。基于这一特点,NAT穿透技术是让NAT背后的设备,先访问指定的外网服务器,由指定的外网服务器搭建桥梁,打通内、外网设备的访问通道,实现外网设备访问到内网设备。
该技术除了可以访问隐藏在NAT后的设备,同样可以穿透防火墙。这是因为防火墙一般只拦截了入站没有拦截出站,所以也可以让防火墙内的设备对外提供服务。
由于内网设备并不是与外网设备直接相连,所以在安全性上是毋庸置疑的,内网穿透可以说是安全与效率兼得。
图8 内网穿透直观理解什么是内网穿透? - NATAPP-内网穿透 基于ngrok的国内高速内网映射工具
2.2 常用NAT穿透工具
ngrok方式:- Ngrok ngrok是一个反向代理,通过在公共端点和本地运行的 Web 服务器之间建立一个安全的通道,实现内网主机的服务可以暴露给外网。ngrok 可捕获和分析所有通道上的流量,便于后期分析和重放,所以ngrok可以很方便地协助服务端程序测试。
参考教程: ngrok搭建指南
- Natapp NATAPP是基于ngrok的国内高速内网穿透服务,其中免费版本提供http,https,tcp全隧道穿透,随机域名/TCP端口,不定时强制更换域名/端口,自定义本地端口 。
参考教程: NATAPP搭建指南
- Sunny-Ngrok Sunny-Ngrok提供免费内网穿透服务,免费服务器支持绑定自定义域名、管理内网服务器,内网web进行演示、本地WEB外网访问、本地开发微信、TCP端口转发
参考教程: Sunny-Ngrok使用教程
- 小米球 小米球旨在给程序猿们调试本地的web项目,免去部署环节,它是提供给有需要的同学免费使用的。
参考教程: 使用教程
SSHSSH自动重新启动SSH会话和隧道。SSH工具是一个非常强大的工具,除了能够远程连接,还能建立隧道,转发端口。利用这个特性就可以把外网的端口请求,连接到内网端口。SSH本身的连接并不稳定,借助工具autossh可以很稳定的建立隧道,因为失败或者其他网络情况下,autossh会自动维护和保持连接。
参考教程:SSH内网穿透
花生壳花生壳是一个动态域名解析软件。当您安装并注册花生壳动态域名解析软件,无论您在任何地点、任何时间、使用任何线路,均可利用这一服务建立拥有固定域名和最大自主权的互联网主机。“花生壳动态域名解析软件”支持的线路包括普通电话线、
ISDN、
ADSL、有线电视网络、双绞线到户的宽带网和其它任何能够提供互联网真实IP的接入服务线路,而无论连接获得的IP属于动态还是静态。
2.3 NATAPP配置使用
图9 natapp使用 推荐使用NATAPP,首先官方注册获authtoken,然后官方下载客户端,并配置config.ini,接着执行./natapp启动,如需后台启动执行
nohup ./natapp & >natapp.log图9 natapp authtoken[default]authtoken=xxxx #对应一条隧道的authtokenclienttoken= #对应客户端的clienttoken,将会忽略authtoken,若无请留空,log=none #log 日志文件,可指定本地文件, none=不做记录,stdout=直接屏幕输出 ,默认为noneloglevel=ERROR #日志等级 DEBUG, INFO, WARNING, ERROR 默认为 DEBUGhttp_proxy= #代理设置 如 http://10.123.10.10:3128 非代理上网用户请务必留空
3 开发调试环境搭建(Java)
3.1 JDK安装
图10 Unix JDK环境变量配置参考教程 JDK Installation Guide
3.2 Maven安装
图11 Unix maven环境变量配置参考教程 https://maven.apache.org/install.html3.3 Tomcat安装
官网下载安装包,解压,然后配置环境变量即可。
server.xml配置图12 server.xml配置 tomcat配置讲解: <!-- port: 接收shutdown指令的端口,默认仅允许通过本机访问,默认为8005; shutdown:发往此Server用于实现关闭tomcat实例的命令字符串,默认为SHUTDOWN。 使用方式:telnet localhost 8005, 输入SHUTDOWN即可关闭tomcat。 --> <Server port="8005" shutdown="SHUTDOWN"> <!-- 默认配置的Listener --> <Listener className="org.apache.catalina.startup.VersionLoggerListener" /> <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> <!-- 应用于整个服务器的JNDI映射,此可以避免每个Web应用程序都需要在各自的web.xml创建, 这在web应用程序以WAR的形式存在时尤为有用。 --> <GlobalNamingResources> <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /> </GlobalNamingResources> <!-- Service是多个Connector和单个Container的组合。Container是一个抽象的概念,由Engine, Realm,Valve和Hosts主组组成。 在server.xml配置文件中可以同时配置多个Service标签 --> <Service name="Catalina"> <!--The connectors can use a shared executor, you can define one or more named thread pools --> <!-- 默认情况下,每个连接器connector会使用自己创建的线程池,我们也可以配置多个线程池让连接器共享--> <!-- 如果想让连接器connector组件使用这个线程池,需要在连接器组件中配置executor属性. 另外,Executor元素的配置应该放在Connector配置的前面,这样才会先加载Executor的配置。 Executor的主要属性包括: - name:该线程池的名称id - maxThreads:线程池中最大活跃线程数,默认值200 - minSpareThreads:线程池中保持的最小线程数,最小值是25 - maxIdleTime:线程空闲的最大时间,当空闲超过该值时关闭线程(除非线程数小于 minSpareThreads),单位是ms,默认值60000(1分钟) - daemon:是否后台线程,默认值true - threadPriority:线程优先级,默认值5 - namePrefix:线程名字的前缀,线程池中线程名字为:namePrefix+线程编号 --> <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/> <!-- A "Connector" represents an endpoint by which requests are received and responses are returned. Documentation at : Java HTTP Connector: /docs/config/http.html Java AJP Connector: /docs/config/ajp.html APR (HTTP/AJP) Connector: /docs/apr.html Define a non-SSL/TLS HTTP/1.1 Connector on port 8080 --> <!-- Connector是Tomcat中请求接收和响应返回的端点,Tomcat中支持HTTP、AJP和APR等协议。 下面的配置定义了一个支持Http协议的连接器,监听80端口 Connector组件支持以下组件的配置: - address:指定连接器监听的地址,默认为所有地址,即0.0.0.0; - port:监听的端口,默认为0; - protocol:连接器使用的协议,默认为HTTP/1.1,定义AJP协议时通常为AJP/1.3; - connectionTimeout:等待客户端发送请求的超时时间,单位为毫秒,默认为60000,即1分钟; - maxThreads:支持的最大并发连接数,默认为200; - redirectPort:如果某连接器支持的协议是HTTP,当接收客户端发来的HTTPS请求时, 则转发至此属性定义的端口; - enableLookups:是否通过request.getRemoteHost()进行DNS查询以获取客户端的主机名; 默认为true; - acceptCount:设置等待队列的最大长度; - executor:指定共享的线程池组件; --> <Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" executor="tomcatThreadPool" /> <!-- 下面是进行支持Https的配置 --> <!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 This connector uses the NIO implementation. The default SSLImplementation will depend on the presence of the APR/native library and the useOpenSSL attribute of the AprLifecycleListener. Either JSSE or OpenSSL style configuration may be used regardless of the SSLImplementation selected. JSSE style configuration is used below. --> <!-- <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateKeystoreFile="conf/localhost-rsa.jks" type="RSA" /> </SSLHostConfig> </Connector> --> <!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2 This connector uses the APR/native implementation which always uses OpenSSL for TLS. Either JSSE or OpenSSL style configuration may be used. OpenSSL style configuration is used below. --> <!-- <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol" maxThreads="150" SSLEnabled="true" > <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" /> <SSLHostConfig> <Certificate certificateKeyFile="conf/localhost-rsa-key.pem" certificateFile="conf/localhost-rsa-cert.pem" certificateChainFile="conf/localhost-rsa-chain.pem" type="RSA" /> </SSLHostConfig> </Connector> --> <!-- Define an AJP 1.3 Connector on port 8009 --> <!-- <Connector protocol="AJP/1.3" address="::1" port="8009" redirectPort="8443" /> --> <!-- Tomcat内部有4个级别的容器,分别是Engine、Host、Context和Wrapper。 Engine代表全局Servlet引擎,每个Service组件只能包含一个Engine容器组件, 但Engine组件可以包含若干Host容器组件 --> <!-- An Engine represents the entry point (within Catalina) that processes every request. The Engine implementation for Tomcat stand alone analyzes the HTTP headers included with the request, and passes them on to the appropriate Host (virtual host). Documentation at /docs/config/engine.html --> <!-- You should set jvmRoute to support load-balancing via AJP ie : <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1"> --> <Engine name="Catalina" defaultHost="localhost"> <!--For clustering, please take a look at documentation at: /docs/cluster-howto.html (simple how to) /docs/config/cluster.html (reference documentation) --> <!-- <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> --> <!-- Use the LockOutRealm to prevent attempts to guess user passwords via a brute-force attack --> <Realm className="org.apache.catalina.realm.LockOutRealm"> <!-- This Realm uses the UserDatabase configured in the global JNDI resources under the key "UserDatabase". Any edits that are performed against this UserDatabase are immediately available for use by the Realm. --> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <!-- 配置虚拟主机,可以配置多个--> <!-- 一个Host下面可以有多个Context,也就是可以部署多个Webapp应用,一个webapp对应一个Context, 用不同的ContextPath区分 --> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <!-- SingleSignOn valve, share authentication between web applications Documentation at: /docs/config/valve.html --> <!-- <Valve className="org.apache.catalina.authenticator.SingleSignOn" /> --> <!-- Access log processes all example. Documentation at: /docs/config/valve.html Note: The pattern used is equivalent to using pattern="common" --> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> <!-- Host下面也可以配置Context相关的配置 --> <Context path="/" docBase="../webapps/weixin_jueye.war" reloadable="true" crossContext="true" /> </Host> </Engine> </Service></Server>
部署时候,将war包放入$tomcat_home/webapps下
另外介绍Ubuntu20下生产环境安装Tomcat例子第1步:安装JavaTomcat要求在服务器上安装Java,以便可以执行任何Java Web应用程序代码。可以通过apt-get安装OpenJDK。
#更新apt-get包索引:sudo apt-get update#安装JDKsudo apt-get install default-jdk
图13 检查java是否成功安装 第2步:创建Tomcat用户 出于安全考虑,Tomcat应该作为非特权用户运行(即不是root用户)。我们将创建一个将运行Tomcat服务的新用户和组。
sudo groupadd tomcat#创建tomcat用户,使该用户成为tomcat组的成员,其主目录为/opt/tomcat,#shell为 /bin/false(因此没有人可以登录该帐户)sudo useradd -s /bin/false -g tomcat -d /opt/tomcat tomcat
第3步:安装Tomcat 在Tomcat 8下载页面上找到版本的Tomcat 8 。
图14 tomcat下载curl -O https://dlcdn.apache.org/tomcat/tomcat-8/v8.5.81/bin/apache-tomcat-8.5.81.tar.gzsudo mkdir /opt/tomcat sudo tar xzvf apache-tomcat-8*tar.gz -C /opt/tomcat --strip-components=1
第4步:更新权限cd /opt/tomcat#在整个安装目录中授予tomcat组权限sudo chgrp -R tomcat /opt/tomcat#为tomcat组提供对conf目录及其所有内容的读访问权限,并执行对目录本身的访问sudo chmod -R g+r conf sudo chmod g+x conf#将tomcat用户设置为webapps,work,temp,和logs目录的所有者:sudo chown -R tomcat webapps/ work/ temp/ logs/
第5步:创建systemd服务文件 将Tomcat作为服务运行,可以设置systemd服务文件。
Tomcat需要知道Java的安装位置。此路径通常称为“JAVA_HOME”。查找该位置的最简单方法是运行此命令:
sudo update-java-alternatives -l
java-1.8.0-openjdk-amd64 1081 /usr/lib/jvm/java-1.8.0-openjdk-amd64
可以通过获取最后一列的输出并附加
/jre
到结尾来构造正确的变量
JAVA_HOME
。
JAVA_HOME /usr/lib/jvm/java-1.8.0-openjdk-amd64/jre
创建systemd服务文
tomcat.service
的文件:
sudo nano /etc/systemd/system/tomcat.service
[Unit]Description=Apache Tomcat Web Application ContainerAfter=network.target[Service]Type=forkingEnvironment=JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-amd64/jreEnvironment=CATALINA_PID=/opt/tomcat/temp/tomcat.pidEnvironment=CATALINA_HOME=/opt/tomcatEnvironment=CATALINA_BASE=/opt/tomcatEnvironment='CATALINA_OPTS=-Xms512M -Xmx2G -server -XX:+UseParallelGC'Environment='JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom'ExecStart=/opt/tomcat/bin/startup.shExecStop=/opt/tomcat/bin/shutdown.shUser=tomcatGroup=tomcatUMask=0007RestartSec=10Restart=always[Install]WantedBy=multi-user.target
#重新加载systemd守护程序,以便它知道我们的服务文件:sudo systemctl daemon-reload#启动Tomcat服务:sudo systemctl start tomcat#检查状态sudo systemctl status tomcat
步骤6:调整防火墙并测试Tomcat服务器 Tomcat使用端口
8080
接受传统请求。输入以下内容允许到该端口的流量:
sudo ufw allow 8080
http://xxx:8080
使Tomcat跟随系统启动:
sudo systemctl enable tomcat
Tomcat就已经安装好了,接下来部署应用程序即可。
参考教程 Apache Tomcat 8 (8.5.81) - Tomcat Setup
如何在Ubuntu 16.04上安装Apache Tomcat 8
3.4 Nginx反向代理安装
3.4.1 docker方式docker pull nginxocker run -p 80:80 --name nginx -v /Users/soledede/Documents/tool/nginx/html:/usr/share/nginx/html -v /Users/soledede/Documents/tool/nginx/nginx/nginx.conf:/etc/nginx/nginx.conf -v /Users/soledede/Documents/tool/nginx/logs/:/usr/share/nginx/logs -d nginx:latest
参考教程:Docker Hub
3.4.2 操作系统方式 这里我们以
Ubuntu20为例。
sudo apt update#安装nginxsudo apt install nginx#调整防火墙sudo ufw app listsudo ufw allow 'Nginx Full'sudo ufw statussudo systemctl status nginx
参考教程:如何在 Ubuntu 20.04 上安装 Nginx
反向代理配置例子:
user www-data;worker_processes auto;pid /run/nginx.pid;include /etc/nginx/modules-enabled/*.conf;events { worker_connections 768; # multi_accept on;}http { ## # Basic Settings ## sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; # server_tokens off; # server_names_hash_bucket_size 64; # server_name_in_redirect off; include /etc/nginx/mime.types; default_type application/octet-stream; ## # SSL Settings ## ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE ssl_prefer_server_ciphers on; ## # Logging Settings ## access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; ## # Gzip Settings ## gzip on; # gzip_vary on; # gzip_proxied any; # gzip_comp_level 6; # gzip_buffers 16 8k; # gzip_http_version 1.1; # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; ## # Virtual Host Configs ##server { listen 80; server_name xhaijy.com; #定义服务器的默认网站根目录位置 #jsp网站程序根目录,一般nginx与tomcat在同一个目录 root /opt/tomcat/webapps/ROOT; location / { #jsp网站程序根目录,一般nginx与tomcat在同一个目录 root /opt/tomcat/webapps/ROOT; index index.html index.jsp index.htm index.php; } location ~ .*.(jsp|do)$ { root /opt/tomcat/webapps/ROOT; index index.jsp; proxy_pass http://127.0.0.1:8080; #来自jsp请求交给tomcat处理 proxy_redirect off; proxy_set_header Host $host; #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 100m; #允许客户端请求的最大单文件字节数 client_body_buffer_size 1024k; #缓冲区代理缓冲用户端请求的最大字节数 proxy_connect_timeout 300s; proxy_send_timeout 900; proxy_read_timeout 900; proxy_buffer_size 32k; proxy_buffers 64 4k; proxy_buffering off; proxy_busy_buffers_size 128k; proxy_hide_header Vary; proxy_set_header Accept-Encoding ''; proxy_set_header Referer $http_referer; proxy_set_header Cookie $http_cookie; proxy_set_header X-Forwarded-Proto $scheme; } location ~ .*/.(gif|jpg|png|bmp|swf)$ #由nginx处理静态页面 { expires 30d; #使用expires缓存模块,缓存到客户端30天 } location ~ .*/.(jsp|js|css)?$ { expires 1d; }} include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*;}
3.5 Mysql 安装
sudo apt install mysql-server
MySQL服务管理sudo service mysql status # 查看服务状态sudo service mysql start # 启动服务sudo service mysql stop # 停止服务sudo service mysql restart # 重启服务
MySQL密码重置sudo mysqlALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '新密码';FLUSH PRIVILEGES;
开启远程登录#新建一个 host 为 % 的 root用户create user 'root'@'%' identified by 'yourpassword';#授权GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;#刷新权限FLUSH PRIVILEGES;#查看用户信息情况use mysqlselect host,user,authentication_string from user;
还需要修改配置文件,允许远程登录。
sudo systemctl stop mysqlsudo vim /etc/mysql/mysql.conf.d/mysqld.cnf#注释掉bind-address这一行#bind-address = 127.0.0.1
可能遇到的问题:1251- Client does not support authentication protocol requested by server...
解决方法: 方法1.升级navicat驱动。
方法2.把mysql用户登录密码加密规则还原成mysql_native_password。
方法2具体操作步骤如下:
#更新user为root,host为% 的密码为yourpasswdALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'yourpasswd';#更新user为root,host为localhost 的密码为yourpasswdALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'yourpasswd';或者#修改加密规则 ALTER USER 'root'@'localhost' IDENTIFIED BY 'yourpasswd' PASSWORD EXPIRE NEVER; #更新一下用户的密码 ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'yourpasswd'; #刷新权限FLUSH PRIVILEGES;
3.6 Idea本地开发调试环境配置
4 生产环境准备
4.1 服务器准备
自己购买服务器,或者购买阿里云、腾讯云、华为云、AWS、微软云等;
4.2 域名以及网站备案
域名申请可以去阿里云或其他服务商进行申请即可。
国内网站备案是指的根据国家的法律法规需要进行实名备案和内容审核,国内的网站备案主要分 ICP 备案和公安备案,网站备案与否是根据提供的服务器 IP 来分别的,只有国内服务器的 IP 才需要进行备案,而
国外服务器不属于国内也不用备案,国内的港澳台地区免备案属于国内仅有的特殊情况。
国内网站备案流程:提供域名实名认证信息,初审,短信验证,终审,阿里云备案还要官方通过电话确定网站信息,比如:是否是本人,网站是做什么之类的。一般备案时间在 7-20 天左右,每个地区时间不一。
4.3 生产环境搭建
环境根据自己的开发语言和业务进行设置,如果是Java可以参考第3节。
5 对话系统介绍
小虎AI珏爷:论文解析 DIET:Dual Intent and Entity Transformer(2020)
小虎AI珏爷:多轮对话 Transformer Embedding Dialogue (TED) Policy 论文解析(2020)
Google
对话系统平台体验:
https://dialogflow.cloud.google.com/6 代码
课件以及
github代码仓库,请在 小虎AI珏爷 公众号聊天框输入
微信公众号 获取。
现有华为云、阿里云服务器配置
内存>=16G、
CPU>=8核、
带宽>=3MBbps可以共享使用,以降低成本,
成本在:
0.8元/天(292元/年),也可以开放子域名您使用,感兴趣的可以联系我。
云厂商服务器618活动期间单独租用成本如下:
华为云:百度:阿里云