时间很长;现在很短;距离很长;相遇很短
Code Jam
教学贴:如何编写Maven2插件
May 26th
Maven插件的编写非常容易,所以,简单的几个流水帐吧。
创建插件工程
# mvn archetype:generate
选择12,回答groupId,artifactId之类的问题,工程就OK了。导入到喜欢的IDE吧。
定义插件参数
完成的定义请参考Maven官方教程,这里简要介绍。
Maven2使用了很多注释中的Annotation来定义插件行为,完整文档点这里,常见的如:
|
Annotation |
功能介绍 |
|---|---|
| @goal <goalName> | 所谓目标了。每个Mojo类包含一个目标,一个Plugin可能若干Mojo类也就有若干目标了 |
|
@parameter expression="${aSystemProperty}" default-value="${anExpression}" |
这是用于Mojo的属性的,可以通过表达式来获取系统参数,项目参数,以及从命令行输入参数。 |
| @required | 同样用于Mojo的属性,定义该参数为必须的。 |
下面是简单的代码
package com.yuchengtech.emp;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.File;
import java.net.URL;
import java.util.Collection;
import java.util.Iterator;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.xmlrules.DigesterLoader;
import org.apache.commons.io.FileUtils;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
/**
* 用于编译EMP相关文件,生成部署资源
*
* @goal emp-compile
*
* @phase process-sources
*/
public class EmpCompileMojo extends AbstractMojo {
/**
* 输出文件路径
*
* @parameter expression=
* "${project.build.directory}/${project.build.finalName}/WEB-INF/tables"
* @required
*/
private File outputDirectory;
/**
* EMP设计文件路径
*
* @parameter expression="${emp.design.dir}"
* @required
*/
private File empDesignDir;
public void execute() throws MojoExecutionException {
getLog().info("Design Files Folder: " + empDesignDir.getAbsolutePath());
getLog().info(
"Output Table Files Folder: "
+ outputDirectory.getAbsolutePath());
URL rule = this.getClass().getClassLoader().getResource(
"rule-table.xml");
Digester digester = DigesterLoader.createDigester(rule);
Collection files = FileUtils.listFiles(empDesignDir,
new String[] { "table" }, true);
for (Iterator it = files.iterator(); it.hasNext();) {
File table = (File) it.next();
getLog().info("EMP: covert file - " + table.getName());
ModelConverter convert = new ModelConverter(table, outputDirectory,
digester);
StringBuffer s = new StringBuffer();
boolean result = convert.convert(s);
if (!result) {
throw new MojoExecutionException(s.toString());
}
}
}
}
发布插件
使用简单的mvn install 之后就可以在本地使用这个插件了。或者发布到公共服务器上供更多人使用。
可以在项目中用命令行 mvn groupId:artifactId:goal来执行插件操作,也可以在项目POM中配置。
请继续参看Maven官方教程。
继续说Apache的优化
May 23rd
经过了前面一段时间的探索,我们对Apache和MySql的性能调优有了个初步的认识,我本来以为问题到这里应该就解决了,但是运行了十几天后,还是出现了负载达到50+的情况。于是,网站又挂了。
分析access.log与之前并无不同,被盗链的请求还是很多,不过这些都被302重定向了啊,死活想不到办法,一度怀疑是不是因为302或者404的错误日志过多的引起的IO问题导致服务器资源紧张。
除此之外,还是有个现象引起了注意,每次挂掉的不是Apache,而是数据库。为什么盗链会引起数据库问题,这显然无法解释。
不绕圈子了,最后发现的问题,就是为了防盗链而特意写的Rewrite。原本的rewrite是这样的,对于盗链的资源,重定向到首页。
这看起来没有问题,可是瞬间请求数百次到首页,然后运行脚本,执行数据库查询……
还有一点,返回的是302,这就意味着搜索引擎和下载工具会认为资源是存在的,不会停止响应。
所以,最终的解决方案。重定向所有盗链的资源到一个静态LOGO,同时,设定返回Code为403.
整个世界清净了。
性能调优:MySql Server at Linux
May 10th
我们继续性能调优系列。
从过前两天的努力,再加上Cache和其他优化,系统的负载由原来的动不动10+下降到了1左右。这应当是巨大的变化,但是一段时间后发现,系统还是有不稳定的情况,CPU有时会莫名的高涨,虽然之前对Apache和PHP的限制使得系统有一点的稳定性,在大多数情况下可以在一段时间后恢复。不过凡事都应有个结局,对吧,找出问题是怪黍蜀的天性……
轮到了MySql, 现代系统,数据库基本上是应用的核心。系统后期再去调优基本上已经是木已成舟司马当作活马医,不过验尸为以后积攒经验还是必要的。再次多余一句,请尽可能优雅的设计数据库。
设计到达一定阶段,就是应用了。这个时候可以进行SQL的Debug, 善用执行计划,调整索引和存储策略,参看Wiki 查询计划
好了,如果这些都没问题了,或者你没办法做这些事情了,就剩下数据库系统的调优了。Database Tuning 这是个多少有点复杂的主题,不过今天介绍的东西只要理解相关概念就可以了。
用于MySql调优的诊断脚本
MySqlTuner 是一个Perl脚本,简单好用。
下载脚本
修改脚本,增加执行权限
chmod +x mysqltuner-1.0.0.pl
运行
./mysqltuner-1.0.0.pl
程序输出
>> MySQLTuner 1.0.0 – Major Hayden <major@mhtx.net>
>> Bug reports, feature requests, and downloads at http://mysqltuner.com/
>> Run with ‘–help’ for additional options and output filtering
Please enter your MySQL administrative login: root
Please enter your MySQL administrative password:——– General Statistics ————————————————–
[--] Skipped version check for MySQLTuner script
[OK] Currently running supported MySQL version 5.0.45-log
[OK] Operating on 32-bit architecture with less than 2GB RAM——– Storage Engine Statistics ——————————————-
[--] Status: -Archive -BDB -Federated +InnoDB -ISAM -NDBCluster
[--] Data in MyISAM tables: 89M (Tables: 147)
[--] Data in InnoDB tables: 27M (Tables: 157)
[--] Data in MEMORY tables: 126K (Tables: 2)
[!!] Total fragmented tables: 12——– Performance Metrics ————————————————-
[--] Up for: 16h 33m 50s (480K q [8.050 qps], 28K conn, TX: 94M, RX: 95M)
[--] Reads / Writes: 75% / 25%
[--] Total buffers: 88.0M global + 2.7M per thread (60 max threads)
[OK] Maximum possible memory usage: 249.2M (49% of installed RAM)
[OK] Slow queries: 0% (18/480K)
[OK] Highest usage of available connections: 33% (20/60)
[OK] Key buffer size / total MyISAM indexes: 32.0M/17.2M
[OK] Key buffer hit rate: 99.6% (3M cached / 15K reads)
[OK] Query cache efficiency: 72.3% (248K cached / 344K selects)
[!!] Query cache prunes per day: 36459
[OK] Sorts requiring temporary tables: 0% (3 temp sorts / 26K sorts)
[OK] Temporary tables created on disk: 21% (3K on disk / 14K total)
[OK] Thread cache hit rate: 97% (765 created / 28K connections)
[OK] Table cache hit rate: 28% (351 open / 1K opened)
[OK] Open file limit used: 31% (343/1K)
[OK] Table locks acquired immediately: 99% (193K immediate / 193K locks)
[OK] InnoDB data size / buffer pool: 27.1M/30.0M——– Recommendations —————————————————–
General recommendations:
Run OPTIMIZE TABLE to defragment tables for better performance
MySQL started within last 24 hours – recommendations may be inaccurate
Variables to adjust:
query_cache_size (> 8M)
注意标注!!!的提示,同时脚本给出了若干优化意见。根据经验分析和修改就可以了。
顺带定时检查和优化表的cron
mysqlcheck -Aao -auto-repair -u root –password=*password* >/dev/null
同时给出 /etc/my.cnf参考配置
[mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # Default to using old password format for compatibility with mysql 3.x # clients (those using the mysqlclient10 compatibility package). old_passwords=1 #skip-locking skip-bdb # MySQL 4.x has query caching available. # Enable it for vast improvement and it may be all you need to tweak. query_cache_type=1 query_cache_limit=1M query_cache_size=8M # max_connections=500 # Reduced to 200 as memory will not be enough for 500 connections. # memory=key_buffer+(sort_buffer_size+read_buffer_size)*max_connections # which is now: 64 + (1 + 1) * 200 = 464 MB # max_connections = approx. MaxClients setting in httpd.conf file # Default set to 100. max_connections=60 #interactive_timeout=180 interactive_timeout=100 #wait_timeout=180 #wait_timeout=100 # Reduced wait_timeout to prevent idle clients holding connections. #wait_timeout=30 wait_timeout=15 connect_timeout=10 # max_connect_errors is set to 10 by default #max_connect_errors=10 #table_cache=512 # Checked opened tables and adjusted accordingly after running for a while. table_cache=512 #tmp_table_size=32M #max_heap_table_size=32M #thread_cache=128 # Reduced it to 32 to prevent memory hogging. Also, see notes below. thread_cache=4 thread_cache_size=4 # key_buffer=258M # Reduced it by checking current size of *.MYI files, see notes below. key_buffer=32M # Commented out the buffer sizes and keeping the default. # sort_buffer_size=2M by default. #sort_buffer_size=1M # read_buffer_size=128K by default. #read_buffer_size=1M # 1Mb of read_rnd_buffer_size for 1GB RAM -- see notes below. # read_rnd_buffer_size=256K by default. #read_rnd_buffer_size=1M # myisam_sort_buffer_size used for ALTER, OPTIMIZE, REPAIR TABLE commands. # myisam_sort_buffer_size=8M by default. #myisam_sort_buffer_size=64M # thread_concurrency = 2 * (no. of CPU) thread_concurrency=2 innodb_buffer_pool_size=30M # log slow queries is a must. Many queries that take more than 2 seconds. # If so, then your tables need enhancement. log_slow_queries=/var/log/mysqld.slow.log long_query_time=2