系统架构
1、客户层
js, css, data的结合
js数据模版
html模版
js加载效率的提升, 因为在无法避免js的数量的增多, 体积的增大的情况下。 如何有效的加载js就显的尤为重要。采用以下方法
a、动态加载js, 不说了, 直接上代码:
- Skip.getJSActionByAjax1 = function (rootObject, url) {
- var myAjax = new Ajax.Request(url, {
- method : "get",
- asynchronous : false,
- onSuccess : function(request) {
- var text = request.responseText;
- //alert(text);
- //Skip.includeJsText(rootObject,text);
- Skip.includeJsSrc( rootObject, url);
- },
- onFailure : function(request) {
- alert("出错了!" + "\n" + request + "\n" + request);
- return result;
- }
- });
- }
- //导入文件
- Skip.includeJsSrc =function (rootObject, fileUrl){
- if ( rootObject != null ){
- var oScript = document.createElement( "script" );
- oScript.type = "text/javascript";
- oScript.src = fileUrl;
- rootObject.appendChild(oScript);
- }
- }
【注明:这里用到了prototype.js】
- var myjslist= new Array();
- //执行时间的方法
- function dyloadjs(fileName, funcJs,showReVal,e,fieldName2,funcName2){
- //alert(fileName);
- var find = true;
- for(var i=0;i<myjslist.length;i++)
- {
- if(myjslist[i]==fileName) {
- find = false;
- break;
- }
- }
- if(find) {
- myjslist.push(fileName);
- var rootObject=document.getElementById("myjs");
- Skip.getJSActionByAjax1(rootObject,fileName);
- Skip.getJSActionByAjax1(rootObject,fileName);
- //Skip.includeJsSrc( rootObject, fileName);
- }
- //TODO
- //调用js函数, 运行
- }
这个地方有个问题 getJSActionByAjax1 方法被调用了2次,
因为在ie8下面, 如果不调用2次, 就没有效果, 始终方法找不到,ie9下面就没有问题,
chrome, safiri等高档浏览器, nnd, 加载js就不是阻塞的, 所以, 这种方式无效, 因为没有等js加载完
就开始执行下面的方法了。 】
采用了这个办法, 可以有效的控制js的加载的顺序, 有图有真相:
js的加载按照预期的方式进行, 把js的加载的事情分割到了不同的时间和区域, 这样可以有效的改善用户体验
但是仔细看上图, 可以清楚的发现js每个都加载了3次, 是因为上面的方法被调用了2次ajax请求, ajax成功以后还有一次是include js src的请求,
但是为啥不是4次, 这个地方有写疑问,难道ie自己发现已经script头有了, 就不在重复加载了?
这个地方滋生了2个问题
1、如何有效的js的请求次数从3次变成1次呢, 好像这个不太可能。最主要直接create script dom节点的话, 不能阻塞加载的线程, 所以这个
问题暂时放一下
2、换个思路, 能不能减少ajax的请求时间呢? 答案是完全可以的。如果这样的话, 后面的时间都是0的话,完全可以弥补次数多的遗憾, 还有什么
比耗费0时间效率更高呢。
b、设定js的过期时间expires 属性, (这个应该是见效最明显的办法了) , tomcat加配置简单易用, 以tomcat7为例:
- <filter>
- <filter-name>ExpiresFilter</filter-name>
- <filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class>
- <init-param>
- <param-name>ExpiresByType image</param-name>
- <param-value>access plus 10 minutes</param-value>
- </init-param>
- <init-param>
- <param-name>ExpiresByType text/css</param-name>
- <param-value>access plus 10 minutes</param-value>
- </init-param>
- <init-param>
- <param-name>ExpiresByType application/javascript</param-name>
- <param-value>access plus 10 weeks</param-value>
- </init-param>
- </filter>
- ...
- <filter-mapping>
- <filter-name>ExpiresFilter</filter-name>
- <url-pattern>/*</url-pattern>
- <dispatcher>REQUEST</dispatcher>
- </filter-mapping>
配置后效果图, 很好很强大。
呵呵, 后面的js的加载时间都变成了0, 哇塞, 这个很好很强大。 对于一些比较稳定的, 少修改的系统来说, 这个参数配置绝对是超值。
同时注意到这个:
- org.apache.catalina.filters.ExpiresFilter
是不是可以重载这个类, 实现自己具体那些文件需要这种处理。
总结: 通过以上2步骤的配置, js的加载基本上通过分时、 分阶段的加载的话。可以有效的改善用户体验。 特别对一些网速比较慢的情况。
2、 web层
负载均衡:
使用nginx做负载均衡
nginx的配置信息如下及字段说明:
- #运行nginx所在的用户名和用户组
- #user nobody;
- #启动进程数
- worker_processes 2;
- #设置全局错误日志存放路径和日志级别
- #error_log logs/error.log debug;
- #error_log logs/error.log info;
- error_log logs/error.log notice;
- #error_log logs/error.log warn;
- #error_log logs/error.log error;
- #error_log logs/error.log crit;
- #pid logs/nginx.pid;
- #设定 nginx 进程可以打开的最大文件描述符数量
- worker_rlimit_nofile 65535;
- #工作模式及连接数上限
- events {
- worker_connections 65535;
- }
- http {
- #设定mime类型
- include mime.types;
- #设置默认的Content-Type,http head中如果没有设置的情况下才会使用
- default_type application/octet-stream;
- #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
- # '$status $body_bytes_sent "$http_referer" '
- # '"$http_user_agent" "$http_x_forwarded_for"';
- #禁止访问日志,启用的话时间长了文件会很大,而且我们暂时不会启用自动脚本清理日志
- #access_log logs/access.log main;
- access_log off;
- # 启用sendfile()函数,大部分情况下提高复制文件的速度
- sendfile on;
- # 配合 sendfile 使用
- tcp_nopush on;
- #keepalive_timeout 0;
- # 客户端到服务器端的连接持续有效时间
- keepalive_timeout 65;
- # gzip 相关设置
- gzip on;
- gzip_min_length 1k;
- gzip_buffers 4 16k;
- gzip_http_version 1.0;
- gzip_comp_level 6;
- gzip_types text/plain text/json text/css text/javascript text/xml application/x-javascript application/xml;
- gzip_vary on;
- # 设置可以在 proxy_pass 中使用的一组代理服务器
- upstream tomcat{
- # max_fails 是检查服务器失败次数,当失败次数达到设定值时停用该服务,0表示关闭检查
- # server 可以设置多个
- server localhost:8888 max_fails=0;
- }
- # 虚拟主机配置
- server {
- # nginx 监听的端口
- listen 8080;
- # 根据客户端请求 header 中的 host 域名匹配响应的虚拟主机
- server_name localhost;
- #============静态文件配置============
- # location 匹配 URI,可以使用字符串,也可以使用正则表达.使用正则表达式时必须使用 ~* 或者 ~ 前缀
- # ~* 前缀表示不区分大小写匹配
- # ~ 前缀表示区分大小写匹配
- # ^~ 前缀表示匹配到字符串后不再取检查正则表达式
- # = 前缀表示精确匹配URI 例如"location = /test"只能匹配"/test",而"test123"则不能被匹配
- location ~* /web/(.*)\.(gif|png|jpg|jpeg|bmp|swf)$ {
- # rewrite 重写url,去掉web等tomcat的webapp名称,为下面的root路径做准备
- rewrite ^/web/(.*)$ /$1 break;
- # 指定请求的文档根目录.
- # 例如 location /i/ {root /home/www/;}时,请求的 URI 是 "/aaa/bb.gif",
- # 则会返回 "/home/www/aaa/bb.gif" 的内容.
- # 即 root 指向的目录内的结构必须和 URI 相同,这与下面的 alias 不一样
- # 并且使用相对路径定位的时候,不是nginx.conf文件所在的路径,
- # 而是编译时指定的prefix路径,或者运行是手动指定的路径,alias定位也是一样
- root "../Web/";
- # 设置 http head 中 "Expires"和"Cache-Control" 的值,负数时"Cache-Control"的值为no-cache
- # off 表示不修改"Expires"和"Cache-Control"的值
- expires 30d;
- }
- #============临时文件路径跳转============
- #error_page 404 /404.html;
- # 50X错误所显示的错误页面
- error_page 500 502 503 504 /50x.html;
- location = /50x.html {
- root html;
- }
- #禁止访问WEB-INF文件夹
- location ~ /(WEB-INF)/{
- deny all;
- }
- # 其他都跳转到tomcat
- location / {
- # 设置代理服务器
- proxy_pass http://tomcat;
- # 设置代理的 http 头中的 host 值为远程连接原本的 host 值
- proxy_set_header HOST $http_host;
- # 设置代理跟后端服务器连接的超时时间.
- # 该时间不是服务器返回页面的事件,而是发起握手等候响应的超时时间.
- # 开发人员调试 java 端程序时可以适当的调长时间,
- # 不然调试时间太长 nginx 会以为后端服务器挂掉而返回500错误.
- # 生产环境中应该设置比较短的时间,不然当后端服务器关闭或者挂掉后 nginx 还在等候,
- # 导致客户端页面在长时间的等待而不是返回错误页面
- proxy_connect_timeout 5s;
- # 关闭对被代理的服务器的应答缓冲
- proxy_buffering off;
- # 客户端允许上传的最大文件大小
- client_max_body_size 500m;
- # 超时必须设置一秒以上,不然IE下载文件会报错
- expires 1s;
- }
- # 这两个路径404时不记录日志
- location = /robots.txt { access_log off; log_not_found off; }
- location = /favicon.ico { access_log off; log_not_found off; }
- }
- }
web服务优化调优--tomcat,
并发数--tomcat
3、业务层
缓存数据
4、数据库层
数据库连接池, 性能监控, 调优
》c3p0的监控
tomcat通过配置jmx可以监控 (资料来源于网络)
- Step1: 配置Tomcat支持JMX
- 在$CATALINA_HOME/bin中找到catalina.sh或者catalina.bat文件,在该文件中添加jmx的配置
- 以catalina.bat为例:
- set CATALINA_OPTS=%CATALINA_OPTS% -Dcom.sun.management.jmxremote
- set CATALINA_OPTS=%CATALINA_OPTS% -Dcom.sun.management.jmxremote.port=9999
- set CATALINA_OPTS=%CATALINA_OPTS% -Dcom.sun.management.jmxremote.authenticate=false
- set CATALINA_OPTS=%CATALINA_OPTS% -Dcom.sun.management.jmxremote.ssl=false
- 表示jmx开放端口是9999
- 配置完以后重启tomcat服务。
- Step2:使用Jconsole监控
- 编写脚本monitor.bat
- 内容是
- jconsole -J-Djava.class.path=%JAVA_HOME%/lib/jconsole.jar;%JAVA_HOME%/lib/tools.jar;c3p0-0.9.1.jar
- Step3:查看结果
- 在jconsole的对话框中输入<hostname>:<port>进入Mbean查看c3p0的信息。
- 如果jconsole连接不上<hostname>:<port>,而telnet可以连接上<hostname>:<port>,那么需要确认在服务器中执行hostname -i看结果是不是你使用<hostname>,如果不是的话要修改/etc/hosts内容。
注明:如果是本机监控的的话, 其实只要直接启动Jconsole,监控tomcat就ok了。 c3p0默认就是jmx方式
》用jsp编程的方式监控jmx(来自网络, 这个好像c3p0的例子)
- <%@ page contentType="text/html;charset=GBK"%>
- <%@ page import="java.sql.*"%>
- <%@ page import="javax.sql.*"%>
- <%@ page import="javax.naming.*"%>
- <%@ page import="com.mchange.v2.c3p0.*"%>
- <%!
- int numConnections=0;
- int numBusyConnections=0;
- int numIdleConnections=0;
- int numUnclosedOrphanedConnections=0;
- %>
- <%
- InitialContext ictx = new InitialContext();
- DataSource ds=null;
- PooledDataSource pds=null;
- try {
- ictx = new InitialContext();
- ds = (DataSource) ictx.lookup("java:comp/env/jdbc/igrp" );
- if ( ds instanceof PooledDataSource) {
- pds = (PooledDataSource) ds;
- String clear=request.getParameter("clear");
- if("1".equals(clear)){
- pds.hardReset();
- }
- numConnections= pds.getNumConnectionsDefaultUser();
- numBusyConnections= pds.getNumBusyConnectionsDefaultUser();
- numIdleConnections= pds.getNumIdleConnectionsDefaultUser();
- numUnclosedOrphanedConnections= pds.getNumUnclosedOrphanedConnectionsDefaultUser();
- }
- else
- System.err.println("Not a c3p0 PooledDataSource!");
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- %>
- <body align="center">
- <table border="1" align="center">
- <tr>
- <td>总的连接数</td>
- <td><%=numConnections%></td>
- </tr>
- <tr>
- <td>正在运行状态的连接数</td>
- <td><%=numBusyConnections%></td>
- </tr>
- <tr>
- <td>空闲连接数</td>
- <td><%=numIdleConnections%></td>
- </tr>
- <tr>
- <td>都是checkoutconnection,但他们已经不在池中管理了.当他们checkin时候,将被destory</td>
- <td><%=numUnclosedOrphanedConnections%></td>
- </tr>
- </table>
- <form action="c3p0.jsp" method="post">
- <input type="hidden" id="clear" name="clear" value="1"/>
- <input type="submit" value="清空连接池"/>
- </form>
- </body>
5、系统测试
6、系统监控、问题扑捉、 调优
验证稳定
验证效率
系统监控
linux: jmap
window:
工具:LR,apache, httpwatch
1、sql语句监控的系统, 包括语句执行的频度, 时间等等, 页面打开时间, 系统的健康程度, 系统运行时间、总访问次数、各种业务的分类统计数据
访问次数, 访问时间范围、 java内存消耗, cpu占用等等。
2、用户行为收集的东东, 用户打开页面的统计, 用户页面停留时间, 页面数据大小 , 可以知道用户操作的习惯, 为系统以后的升级做出更好的修正提供必要的信息
系统监控的
附录:
tomcat并发设置
在tomcat配置文件server.xml中的<Connector ... />配置中,和连接数相关的参数有:
minProcessors:最小空闲连接线程数,用于提高系统处理性能,默认值为10
maxProcessors:最大连接线程数,即:并发处理的最大请求数,默认值为75
acceptCount:允许的最大连接数,应大于等于maxProcessors,默认值为100
enableLookups:是否反查域名,取值为:true或false。为了提高处理能力,应设置为false
connectionTimeout:网络连接超时,单位:毫秒。设置为0表示永不超时,这样设置有隐患的。通常可设置为30000毫秒。
其中和最大连接数相关的参数为maxProcessors和acceptCount。如果要加大并发连接数,应同时加大这两个参数。
- <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
- connectionTimeout="20000"
- redirectPort="8443" />
JVM设置
堆的尺寸
-Xmssize in bytes
设定Java堆的初始尺寸,缺省尺寸是2097152 (2MB)。这个值必须是1024个字节(1KB)的倍数,且比它大。(-server选项把缺省尺寸增加到32M。)
-Xmnsize in bytes
为Eden对象设定初始Java堆的大小,缺省值为640K。(-server选项把缺省尺寸增加到2M。)
-Xmxsize in bytes
设定Java堆的最大尺寸,缺省值为64M,(-server选项把缺省尺寸增加到128M。) 最大的堆尺寸达到将近2GB(2048MB)。
请注意:很多垃圾收集器的选项依赖于堆大小的设定。请在微调垃圾收集器使用内存空间的方式之前,确认是否已经正确设定了堆的尺寸。
垃圾收集:内存的使用
-XX:MinHeapFreeRatio=percentage as a whole number
修改垃圾回收之后堆中可用内存的最小百分比,缺省值是40。如果垃圾回收后至少还有40%的堆内存没有被释放,则系统将增加堆的尺寸。
-XX:MaxHeapFreeRatio=percentage as a whole number
改变垃圾回收之后和堆内存缩小之前可用堆内存的最大百分比,缺省值为70。这意味着如果在垃圾回收之后还有大于70%的堆内存,则系统就会减少堆的尺寸。
-XX:NewSize=size in bytes
为已分配内存的对象中的Eden代设置缺省的内存尺寸。它的缺省值是640K。(-server选项把缺省尺寸增加到2M。)
-XX:MaxNewSize=size in bytes
允许您改变初期对象空间的上限,新建对象所需的内存就是从这个空间中分配来的,这个选项的缺省值是640K。(-server选项把缺省尺寸增加到2M。)
-XX:NewRatio=value
改变新旧空间的尺寸比例,这个比例的缺省值是8,意思是新空间的尺寸是旧空间的1/8。
-XX:SurvivorRatio=number
改变Eden对象空间和残存空间的尺寸比例,这个比例的缺省值是10,意思是Eden对象空间的尺寸比残存空间大survivorRatio+2倍。
-XX:TargetSurvivorRatio=percentage
设定您所期望的空间提取后被使用的残存空间的百分比,缺省值是50。
-XX:MaxPermSize=size in MB
长久代(permanent generation)的尺寸,缺省值为32(32MB)。