生产问题排查与程序设计的一些思考

最近处理生产上的一些问题,对程序设计和编程有了一些新的认识。浅谈一下。

1、Servlet

servlet这个东西,可以用来做对外服务的接口,发布一个上下文就可以使用http调用。也许很多时间我们只是简单地override了doGet和doPost方法,调用业务处理完print回去。如果这个业务处理很费时,那么这个servlet线程就会一直不能回收。我们知道一个tomcat能接受的最大并发是有限的。所以如果servlet容器资源用尽,很难接收后续的http请求。servlet 3.0的新特性async-supported帮我们解决了这个事。它允许我们把servlet线程的业务处理给线程池去做,自身可以马上返回servlet池中。当子线程处理完业务后,再用持有的respone对象输出实际的响应。


2、主线程与子线程

程序使用了httpClient工具,最近发现ajax经常出现java.net.SocketTimeoutException: Read timed out,查了这个请求,是调用应用的一个接口。一开始总是以为可能是网络因素导致超时什么的。看了超时时间,设了10s,够长了,还是会出现。经验丰富的宋工说,看是不是该请求的链过长导致响应慢。有理,查之。发现方法里有一处地方使用HttpClient调用了另一个系统的接口,而这个接口里,有调用中间件写数据库和调用微信接口的操作。所有的代码都是同步的,意味着哪一个地方处理费时,就会导致最开始那个ajax的响应慢甚至超时。

所以啊,设计程序时,要充分知道哪些地方是可能会耗时长的,比如大IO读写,远程调用,读写数据库等等。这些地方,最好是启用单独的线程处理。对于需要返回值的,可以用

Future。如下代码。heavyWork()会做很费时的操作,我们用的一个Future来代替他,主线程中可以asyncGetUser(),把Future引用存在map中,这样主线程可以在其他地方通过future.get()获取到结果,而不是卡在这里。
另外提点建议,程序中一些重要的业务处理,应该针对性地输出执行时间来,比如超过多少秒的,要打印出来,这样出问题好找。
public Future asyncGetUser() {
    Future future = threadPool.submit(new Callable {
        public User call() throws Exception {
            return heavyWork();
        }
    }
    
    return future;
}

3、推送
项目二期客户需要一个推送的 功能。坐席通过在线客服给客户的券商app推送一些消息。这东西不像 IM 那样经常会有数据传输,可能是不定时才会有一两个消息,所以让app一直保持一个socket连接不好,当然这个功能可以已方来做。现在也有很多成熟的推送产品,如百度云,极光等。他们会提供一个要集成到app的sdk,开发用的jar包,一套api,帐号和地址等等。sdk的onNotificationClicked会监测到点击行为并跳转到指定的activity。用户的app是没有集成推送软件的。还有一点是现在的推送产品也是很多,都提供了简单的集成方式和开发要求,也稳定高效,比自己实现好得多。


你可能感兴趣的:(JAVA,设计模式)