作者存档: 朱坤乾 - 第16页

maven中添加war包依赖

maven中添加war包依赖

<project>
  ...
  <build>
    <!-- To define the plugin version in your parent POM -->
    <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.appfuse.plugins</groupId>
                    <artifactId>maven-warpath-plugin</artifactId>
                    <version>2.2.2-SNAPSHOT</version>
                </plugin>
            </plugins>
        </pluginManagement>
    <!-- To use the plugin goals in your POM or parent POM -->
    <plugins>
      <plugin>
           <groupId>org.appfuse</groupId>
                <artifactId>maven-warpath-plugin</artifactId>
                <version>2.0.2</version>
                <extensions>true</extensions>
                <executions>
                    <execution>
                        <goals>
                            <goal>add-classes</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
      ...
    </plugins>
  </build>
  ...
</project>

通常会再添加以下配置将war包中的lib包过滤掉:

                        <plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<configuration>
					<dependentWarExcludes>WEB-INF/lib/*</dependentWarExcludes>
				</configuration>
			</plugin>

添加war包依赖

       <dependency>
            <groupId>cn.kingsoft</groupId>
            <artifactId>game-web</artifactId>
            <version>1.0</version>
            <type>warpath</type>
        </dependency>

cmd命令中显示utf字符

自从项目中所有文件变为utf8字符集后,cmd中就再也没有看到过正确的中文显示。因为cmd默认使用gbk字符集。

以下操作将cmd改为utf8字符集。

1、打开CMD.exe命令行窗口
2、通过 chcp命令改变代码页,UTF-8的代码页为65001(gbk 936)
chcp 65001
执行该操作后,代码页就被变成UTF-8了。但是,在窗口中仍旧不能正确显示UTF-8字符。
3、修改窗口属性,改变字体
在命令行标题栏上点击右键,选择”属性”->”字体”,将字体修改为True Type字体”Lucida Console”,然后点击确定将属性应用到当前窗口。

把java安装为服务

将java安装为服务,强烈推荐common daemon:

http://commons.apache.org/proper/commons-daemon/procrun.html

apache上的多个java项目都使用这个安装为windows服务。

用法很简单:

java类中的main函数中使用start和stop来做为启动和停止指令:

public static void main(String[] args) {
		System.out.println("start Pdf2Swf Service main with args:" + args);

		String mode = "start";
		if (args != null && args.length > 0) {
			mode = args[0];
		}
		if ("start".equals(mode)) {
			// 启动主线程
			Pdf2SwfService pdf2SwfService = new Pdf2SwfService();
			pdf2SwfService.run();
			Pdf2SwfService.staticInstance = pdf2SwfService;
		} else if ("stop".equals(mode)) {
			if (Pdf2SwfService.staticInstance != null) {
				try {
					Pdf2SwfService.stop = true;
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

下面编译安装服务的脚本:

@echo off
cd /d %~dp0
set PR_PATH=%CD%
SET PR_SERVICE_NAME=Pdf2Swf
SET PR_JAR=pdf2swf.jar
SET START_CLASS=org.haifi.Pdf2SwfService
SET START_METHOD=main
SET STOP_CLASS=java.lang.System
SET STOP_METHOD=exit
rem ; separated values
SET STOP_PARAMS=0
rem ; separated values
SET JVM_OPTIONS=-Dapp.home=%PR_PATH% -out %CD%\stdout.log -err %CD%\stderr.log -current %CD%

echo %PR_PATH%

prunsrv.exe //IS//%PR_SERVICE_NAME% --DisplayName="%PR_SERVICE_NAME%" --Install=%PR_PATH%\prunsrv.exe --LogPath=%PR_PATH%\logs --LogLevel=Debug --StdOutput=auto --StdError=auto --StartMode=Java --StopMode=Java --Jvm=auto --StartMode=jvm --StartClass=%START_CLASS% ++StartParams=start --StopMode=jvm --StopClass=%STOP_CLASS% ++StopParams=stop --Classpath="%PR_PATH%\%PR_JAR%"  ++JvmOptions=%JVM_OPTIONS%
pause


上面的类换为自己写的主类名。

如果启动不起来时,注意一下如果jdk为32位版本时,需要使用32位的prunsrv。

如果使用64位的prunsrv,则必须使用64位的jdk版本。

不然会直接提示无法启动,但又不会有任何有用的提示信息。

获得bat文件所在的目录

cd /d %~dp0

编写bat必备内容。

voltdb安装及使用

1、下载voltdb后直接解压:

$ tar -zxvf LINUX-voltdb-ent-3.6.tar.gz

2、两点注意事项,切记切记:

1.1.

Disable Swapping

Swapping is an operating system feature that optimizes memory usage when running multiple processes. However, memory is a critical component of the VoltDB server process. Any contention for memory, including swapping, will have a very negative impact on performance and functionality.

We recommend using dedicated servers and disabling swapping when running the VoltDB database server process. Use the swapoff command to disable swapping on Linux systems. If swapping cannot be disabled for any reason, you can reduce the likelihood of VoltDB being swapped out by setting the kernel parameter vm.swappiness to zero.

voltdb是内存数据库,常驻内存非常重要,因此需要将交换分区(虚拟内存)完全关闭。可以使用swapoff命令关闭,如果无法使用swapoff命令,则将内核参数vm.swappiness修改为0。

1.2.

Turn off TCP segmentation offload and generic receive offload if cluster stability is a problem.

There is an issue where, under certain conditions, the use of TCP segmentation offload (TSO) and generic receive offload (GRO) can cause nodes to randomly drop out of a cluster. The symptoms of this problem are that nodes timeout — that is, the rest of the cluster thinks they have failed — although the node is still running and no other network issues (such as a network partition) are the cause.

Disabling TSO and GRO is recommended for any VoltDB clusters that experience such instability. The commands to disable offloading are the following, where N is replaced by the number of the ethernet card:

ethtool -K ethN tso off
ethtool -K ethN gro off

Note that these commands disable offloading temporarily. You must issue these commands every time the node reboots.

这个是使用集群时需要注意的事项。

3、如果是旧版本升级需要按以下顺序执行:

The process for upgrading VoltDB for a running database is as follows:

    Place the database in admin mode using the @Pause system procedure (or VoltDB Enterprise Manager).

    Perform a manual snapshot of the database (using @SnapShotSave).

    Shutdown the database (using @Shutdown).

    Upgrade VoltDB.

    Recompile the application catalog using the new version of VoltDB.

    Restart the database using the create option, the new catalog, and starting in admin mode (specified in the deployment file).

    Restore the snapshot created in Step #2 (using voltadmin restore).

    Return the database to normal operations (using voltadmin resume).

4、将voltdb添加至环境变量中.

JAVA_HOME=/opt/jdk1.7.0_40
VOLTDB_HOME=/opt/voltdb-3.5.0.1
PATH=$PATH:$HOME/bin:$JAVA_HOME/bin:$VOLTDB_HOME/bin

export JAVA_HOME VOLTDB_HOME PATH

5、以下开始学习使用简单的voltdb命令。

先创建一个指定目录:helloworld

定义表结构:

CREATE TABLE HELLOWORLD (
   HELLO VARCHAR(15),
   WORLD VARCHAR(15),
   DIALECT VARCHAR(15) NOT NULL,
   PRIMARY KEY (DIALECT)
);

decoder解码优化

decoder中需要使用byte[]接收数据并转为protobuf对象。

本来考虑的是使用netty自带的缓存功能或直接在每个decoder中分配一个byte[]。这时想起来了fastjson的作者提过使用的线程绑定的byte[]功能。

查找到源代码,摘出来用。也感谢fastjson的作者开源代码。

package cn.joylab.game.util;

import java.lang.ref.SoftReference;

/**
 * 提供线程绑定数组缓存功能。
 * 
 * 可以避免频繁创建byte数组,最大长度限制为128k,超过128k的数据不进行缓存。
 * 
 * 用例1:decoder.
 * 
 * @author ZhuKunqian
 * 
 */
public class ThreadLocalCache {
	private final static int BYTE_CACHE_INIT_SIZE = 1024;
	private final static int BYTE_CACHE_MAX_SIZE = 1024 * 128;
	private static final ThreadLocal<SoftReference<byte[]>> byteBufLocal = new ThreadLocal<SoftReference<byte[]>>();

	public static void clearCache() {
		byteBufLocal.set(null);
	}

	public static byte[] getBytes(int length) {
		SoftReference<byte[]> ref = byteBufLocal.get();
		if (ref == null) {
			return allocateBytes(length);
		}

		byte[] bytes = ref.get();
		if (bytes == null) {
			return allocateBytes(length);
		}
		if (bytes.length < length) {
			bytes = allocateBytes(length);
		}
		return bytes;
	}

	private static int getAllocateLength(int init, int max, int length) {
		int value = init;
		while (true) {
			if (value >= length) {
				return value;
			}
			value *= 2;
			if (value > max) {
				break;
			}
		}
		return length;
	}

	private static byte[] allocateBytes(int length) {
		int allocateLength = getAllocateLength(BYTE_CACHE_INIT_SIZE,
				BYTE_CACHE_MAX_SIZE, length);
		if (allocateLength <= BYTE_CACHE_MAX_SIZE) {
			byte[] bytes = new byte[allocateLength];
			byteBufLocal.set(new SoftReference<byte[]>(bytes));
			return bytes;
		}
		return new byte[length];
	}
}

 

db的选择

今天仔细看了下voltdb,全内存数据库。

在新项目选择上,主要考查了3个数据库mysql,mongodb,voltdb。

mysql就不需要多说了,传统的关系数据库,而且用了多年,也比较熟悉。

mongodb,nosql数据库,使用二进制json格式保存,支持sql语句。

voltdb,关系数据库,也可当做nosql数据库来用,全内存,支持sql语句。因为是全内存操作,所以速度是非常快的。

mysql,mangodb需要读写磁盘,所以相对要慢一些。但voltdb官方推荐是4G内存启动。虽然也可以1G内存启动起来,会有会有其它后果还不清楚。而且还有一个很恶心的问题,voltdb不像mysql那样或以多个database启动,一个voltdb实例,只是一个database。这还不算问题,如果要在一台机器上开启20个database,则无法像官方所说的那样,按4G内存分配。估计每个database只能分配1G。

但voltdb可以当作一个jar嵌入到工程中,这样可以避免线程中的数据传输,又是一个好处。

voltdb也提供了jdbc driver,因此新项目中可以尝试使用voltdb,如果发现有解决不了的问题,可以直接切换至mysql.

linux查看缺少的so连接库

ldd $(which /usr/local/nginx/sbin/nginx)

以上命令可以查看缺少的so连接库

webtool允许远程访问

webtool:start().启动后,无法远程访问,查看

start(Path,Data)->{ok,Pid}|{stop,Reason}

Types:
Path = string() | standard_path
Data = [Port,Address,Name] | PortNumber | standard_data
Port = {port,PortNumber}
Address = {bind_address,IpNumber}
Name = {server_name,ServerName}
PortNumber = integer()
IpNumber = tuple(), e.g. {127,0,0,1}
ServerName = string()
Pid = pid()

Use this function to start WebTool if the default port, ip-number,servername or path can not be used.

Path is the directory where the mime.types file and WebTool's own HTML files are located. By default this is webtool-<vsn>/priv, and in most cases there is no need to change this. If Path is set to standard_path the default will be used.

If Data is set to PortNumber, the default data will be used for ip-number (127.0.0.1) and server name (localhost).

需要设置bind_address为 0,0,0,0才能远程访问。

启动方式如下:

webtool:start(standard_path,[{port,8888},{bind_address,{0,0,0,0}},{server_name,”server”}]).

第一个erlang application

1、创建目录结构 doc、ebin、include、priv、src

2、在ebin下创建应用描述文件,这里应用取名为 first_app,则创建的描述文件为first_app.app

{application, first_app,
  [{description,  "hello world,first app"},
   {id,           "first_app"},
   {vsn,          "0.1.0"},
   {modules,      [
                        first_app,
                        first_app_sup
                        ]},
   {registered,   "first_app_sup"},
   {applications, [kernel,stdlib]},
   {mod,          {first_app,[]}},
   {start_phases, []}
  ]
}.

3、下面编写 src/first_app.erl,此文件的唯一任务就是启动根监督者。

-module(first_app).

-behaviour(application).

-export([start/2,stop/1]).

start(_StartType,_StartArgs)->
        case first_app_sup:start_link() of
                {ok,Pid} -> {ok,Pid};
                Other    -> {error,Other}
        end.

stop(_State)->
        ok.

4、实现监督者 src/first_app_sup.erl

-module(first_app_sup).

-behaviour(supervisor).

-export([start_link/0,start_child/2]).

-export([init/1]).

-define(SERVER,?MODULE).
start_link()->
        supervisor:start_link({local,?SERVER},?MODULE,[]).

start_child(Value,LeaseTime)->
        supervisor:start_child(?SERVER,[Value,LeaseTime]).

init([])->
        Element={
                first_app_tcp_listener,
                        {first_app_tcp_listener,start_link,[]},
                        permanent,10000,worker,
                        [first_app_tcp_listener]
                },
        Children=[Element],
        RestartStrategy={simple_one_for_one,0,1},
        {ok,{RestartStrategy,Children}}.

5、尝试运行:

先编译为beam

erlc -o ebin src/*.erl

再运行。

在erl中输入

application:start(first_app).

注意:simple_one_for_one需要手动去调用start_child才会产生子进程。


Warning: Use of undefined constant XML - assumed 'XML' (this will throw an Error in a future version of PHP) in /opt/wordpress/wp-content/plugins/wp-syntaxhighlighter/wp-syntaxhighlighter.php on line 1048