最近的一点感慨:团队可以有能力差的人,但不能有懒人。
欢迎关注我的微信公众号: coderbee笔记,可以更及时回复你的讨论。
最近的一点感慨:团队可以有能力差的人,但不能有懒人。
欢迎关注我的微信公众号: coderbee笔记,可以更及时回复你的讨论。
之前的文章提到公司要求项目组做所谓的网络标准化,在 Spring MVC 的 Controller 层与 Service 层之间拆分成两个项目来部署,中间通过 Hessian 远程调用来通信。
这样可就有大问题了:
Controller 调用 Service 的方法时,传递一个 POJO 作为参数,Service 里修改了这个参数的某个属性,最终返还 Controller,Controller 再根据这个被修改的属性继续处理;
Service 调用的深层方法通过 Spring MVC 通过的
org.springframework.web.context.request.RequestContextHolder
获取了HttpSession
对象,然后设置了一些状态值。
在同一 JVM 里面,上面的都没有问题;但按标准化的要求,部署在两个 JVM 上时,Service 层对 Controller 层传入的 POJO 所做的修改在 Controller 层就不可见了。
这些问题是实现这个标准化的最大困难,几乎所有代码都要检查是否存在上面的情况。
上面的问题可以说是“参数的可变性”和“方法副作用”导致的,“参数” 是个特殊的东西,它穿过两个方法之间调用时形成的边界。如果“参数”的属性在被调用的方法里被修改了,可以说这个方法是有副作用的。
如果上天再给一次机会:把所有方法都实现为无副作用,参数封装为不可变的对象,方法的所有效果都通过返回值来体现。这样每一个方法都可以变成一个远程服务。
之前在微博上看到一个说他的架构宣言是:Passing Message Everywhere。有点感触。
欢迎关注我的微信公众号: coderbee笔记,可以更及时回复你的讨论。
业务部门反应网站访问特别慢,负责运维监控的同事说MQ消息队列积压了,中间件的说应用服务器内存占用很高,GC 一直回收不了内存,GC 线程占了近 100% 的 CPU,其他的基本上都在等待,数据库很正常,完全没压力。没啥办法,线程、堆 dump 出来后,重启吧,然后应用又正常了。
这种故障之前其实也碰到过了,分析了当时 dump 出来的堆后发现,处理 MQ 消息的线程池的队列长度达百万级别,占用了超过 1.3G 内存,这些内存都是没法回收的。
程序的实现目前是这样的:关联系统把消息推送到 MQ 上,我们再从 MQ 上拉消息下来处理;每种类型的消息都有一个线程负责从 MQ 上拉消息,拉下来后封装成线程池的任务提交给相应的线程池去执行。代码可以简化为:
package net.coderbee.mq.demo;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MQListener {
public ExecutorService executor = Executors.newFixedThreadPool(8);
public void onMessage(final Object message) {
executor.execute(new Runnable() {
@Override
public void run() {
// 耗时且复杂的消息处理逻辑
complicateHanlde(message);
}
});
}
private void complicateHanlde(Object message) {
}
}
这个问题还是去年在上家公司时碰到的,当时领导要我优化一个后台系统,它的核心逻辑就是接收客户端上传文件,把解析出的信息入库,再把文件上传到一个 FTP 服务器。
搞完之后总得部署到生产环境,因为这是个接手系统,只有源码,也不知道部署结构,只告诉我有两个结点,部署上去之后验证下没问题就行了。
我当时是准备一个一个结点部署的,在 serverA 上更新完成,验证后发现没有问题,然后准备更新 serverB 时,却发现突然又不行了,当时好像是请求没收到还是咋,具体不记得了,只有一个人在那里,折腾很久,最后联系运维人员,人家把双机热备的切换机制给停了才行。
事后分析认为是双机热备切换导致的,主机更新后一开始正常是因为还没有切换到备机上,而主机上的服务很快就起来了,请求仍然是到了主机上,所以一开始验证是可以的,但后来被切换到备机上去了,备机上跑的是旧的程序,请求不会到主机上,在主机上看是怎么也不会知道原因的,还以为程序有问题,当时也不会抓包分析,人都慌了,哈哈。
现在的 web 系统为了达到高可用,都会进行双机热备,就是两台服务器 serverA 和 serverB 上的部署是完全一样的,它们都配置了同一个虚拟 IP,但只有一台机器对外提供服务。如果这台提供服务的机器出故障了,双机热备程序就会自动把请求切换到另一台服务器上,从而保证服务是可用的。但这个切换是有延迟的,取决于双机热备的实现机制和配置。
欢迎关注我的微信公众号: coderbee笔记,可以更及时回复你的讨论。
最近公司的一个系统用上了 CDN 服务,用户反应快多了,那个系统主要是静态资源展示和一些可公开的数据查询服务。另一个项目组的系统A看了也要上,不过这个A的后台代码是放在我所在项目组M里,是同一个应用,都在同一个域名 main.com
下。网络组把 main.com
的 DNS 解析到 CDN 服务器上去之后,访问也是快了,但是用户反应数据乱了,而且有些服务没法用了,后台统计特定地区用户的访问也不准了,因为所有请求基本上都是从几个 IP 里过来的。
稍微对 CDN 有所了解的人看完问题描述之后都会发现问题所在:由于只有一个域名 main.com
,且被解析到 CDN 服务器上,CDN 不仅分发静态资源,还变成代理服务器了,所有动态请求、数据都要经过 CDN 服务器。
很明显,这是错误使用 CDN 带来的问题。这带来的问题不仅是上面描述的问题,更大的业务安全问题:当所有业务数据都经过 CDN 服务器时,CDN 厂商就有了那些业务数据,这相当于把银行卡和密码交给一个中间人,要存钱、取钱的时候就让这个中间人去 ATM/银行 处理,再给自己反馈结果。有这么值得信赖的中间人吗??
随着代码写得越来越烂,程序运行时 数据库操作更多、IO 阻塞等待跟过、不必要的对象创建、GC 回收更频繁,线程的上下文切换也更多,开销越来越多,所有因素综合起来,程序运行更慢,响应延迟加大。
当到达临界点的时候,压垮骆驼的最后一根稻草出现了,系统直接崩溃。
坏东西、副作用是会累积的。
今天跟一个同学聊天,发现很多很好用的工具他都还不知道,我周围的绝大多数同事也不知道。虽然我用的工具不多,用得也不是很深入,但对我的帮助已经非常大,所以写的文字介绍。
首先要说的是浏览器,因为上网大多数都是在浏览器里进行的。我用的是Firefox,因为有很多插件可用。Chrome也不错,只是习惯了火狐。
火狐的一个很重的功能是账号同步功能,可以同步的最重要的两个内容:已安装插件、书签。也就是在办公室的火狐上安装了一个插件或者收藏了一个网址,回家后也有了,不用再搞一遍。换了一台机或重装了系统,登录火狐账号后,一切又回来了。这也是云的作用吧!
现在用的浏览器插件主要有:
里面的路径:/testcopy-moved.txt
, /testcopy.txt
, /abctest/testcopy.txt
, /\x22 + cnzz_protocol + \x22s22.cnzz.com/z_stat.php%3Fid%3D1000033072
,这些路径都不是我的博客里的常规地址,怎么突然有人会去扫描这些路径呢?以前发现的一般都是扫描phpAdmin的。
再想想,记起来了,前面三个路径是我在前一篇博客里介绍我写的Dropbox Go SDK里的例子里有提到,而cnzz那个估计是人家发现我的站点使用cnzz的统计服务。
哈哈,真心佩服搞安全的人的耐心与细心!虽然前三个路径是Dropbox里的虚拟路径。
之前写博客搭建笔记和博客维护脚本时,贴了一些脚本,但没有把没有把所有细节贴出来,本来是想贴的,觉得太麻烦,也算是侥幸了。服务器的具体配置、细节还真不能乱透露,特别要小心无意中泄漏了。
最后,如果哪个大神已经拿下或准备拿下这个VPS时,我只能说:此地真无银三百两!
欢迎关注我的微信公众号: coderbee笔记,可以更及时回复你的讨论。
有同事今天碰到的一个问题:用户访问公网的Nginx服务器,Nginx再把用户请求转发到内网的Tomcat服务器的80端口,现在内网Tomcat服务器的应用想拆分,不同应用用不同的Tomcat来运行,这样就在内网配置了一台Apache(不方便改Nginx的转发规则,那个Nginx是别人弄的),根据应用的url转发到对应的Tomcat。出现的问题是:从公网访问Nginx出现HTTP 400错误,从Apache访问日志可以看到,请求是过来了,但没转发给后端的Tomcat,Apache直接返回400;如果Nginx直接转发到Tomcat也是可以的,从内网通过Apache访问Tomcat也是可以的。
所以问题应该是Nginx到Apache的请求有问题。这个同事知道我以前配置过Nginx,所以找我要Nginx转发到Tomcat的配置。
在本地测试机上,Nginx的转发配置都没问题,从 Nginx --> Tomcat
或者 Nginx --> Apache --> Tomcat
都没问题。
没辙,我只好回自己工位去google。
继续阅读