方案提出的初衷:外网需要定时和不定时推送数据到内网服务器(只要求数据到达内网,没有要求直接连接到内网)
为什么不是直连到内网:每个人第一想到的是不安全,是的,没错不安全。内网的应用和外网的应用最明显的区别就是承载的访问量,虽然都应该配置防恶意攻击策略,但是内网的应用一般不会像外网的应用考虑那么多安全的策略。所以这里的安全,包含防窃取资料的安全性、恶意攻击以及给hacker留了后门等因素。(我想的是这些)
所以,专门留一台外网可以访问的机器A,外网把数据推送到机器A,然后内网的应用B去机器A PULL 数据。
怎么去PULL数据?
有两种方式:
第一,定时去机器A PULL,缺点有延时,如果每隔20分钟取一次数据,最长延时为20分钟。如果外网推送本来就延时推送,那么数据状态实际产生的时间到达数据的最终消费者的时候,延时更长。
第二,监听机器A,当机器A上一旦有可用数据的时候,就PULL过来。(我采用的是这种方案)
监听机器A怎么监听?
第一,可以自己写个程序,建立请求连接,机器A保留连接请求不立即响应,等到机器A上有可用消息的时候,再响应。(相当于我们在HTTP里面经常说的 long connection)
第二,使用MSMQ的reveive方法,这个方法本身就实现了这样的机制,当MSMQ中有可用消息时Receive才返回消息。这里需要合理建立专门的消息队列。
推送消息怎么到达数据消费者C?
监听机器A是否有可用消息的服务,我们暂且称为“数据转发服务B”,转发服务可以独立部署,也可以部署在消费者C里面。
我最初把转发服务部署在IIS上,并且设置应用程序池不回收,即“固定时间间隔”设置为0,“限制超时”也设置为0,但是过几个小时后,这个转发服务还是会“休息”,需要访问这个站点的一个页面,使服务“醒”过来。服务没有死,只是可能闲置了,被回收了。具体原因望高手支招。
后来把转发服务配置到了windows服务,这样不会有应用程序池被回收的问题。
数据消费者C需要公开一个接受“推送数据”的服务,转发服务将PULL得到的数据 转 给 该服务。
这样的完整流程我实现了,目前运行正常,但不知会有什么潜在问题?望高手支招。
以上叙述中,机器A是处于DMZ中的。
备用方案:
由于推送数据经过了两个中间机器,机器A和转发服务处于的机器,如果哪天不能用了,让数据消费者B临时主动请求外网API去获得数据,这样对消费者B是有压力的,所以不建议这样使用。
小插曲,就因为后期做了一个主动请求外网API的备用方案,上线测试的时候,没有考虑到生成环境的数据库有上万的历史数据,导致系统异常发了上万条异常邮件。因此被记过加现金处罚。