AXIS2无法从SOAP MTOM/XOP消息中获取附件

最近,同事在与其他厂商做IHE测试,测试的CASE多数都可以通过。唯独一个测试无法通过:对方需要通过MTOM/XOP消息发送一个文件到我们的服务,我们可以正常的收到消息,但无法解析消息得到附件。

经过沟通,发现另一个厂商居然是用CPP自己手动拼接的SOAP消息,也是醉了。

首先是解决了几个命名空间填写不正确的问题,调整完毕以后,AXIS2会报下面的错误:

org.apache.axiom.om.OMException: javax.xml.stream.XMLStreamException: Expected xop:Include as the sole child of an element information item (see section 3.2 of http://www.w3.org/TR/xop10/). This is due to the fact that the element (<xdsb:Document id="Document01">   </xdsb:Document>)  (OMElement obtained after axis2 processing)  that should contains the base64 value of document, is empty. But observing the same message sniffed from wireshark it seems that the Document is present.

这个问题好诡异啊。

经过一番搜索,在apache找到了答案:
由于对方发送附件时,多了一个换行符(XOP协议明确规定不允许的),导致了该错误的发生:

<xdsb:Document id="Document01"><xop:Include href="cid:1.11a262e2-bf65-1e01-28a7-000c29c7ee2b@apache.org" xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
</xdsb:Document>

去掉换行符以后,就好了:

<xdsb:Document id="Document01"><xop:Include href="cid:1.11a262e2-bf65-1e01-28a7-000c29c7ee2b@apache.org" xmlns:xop="http://www.w3.org/2004/08/xop/include"/></xdsb:Document>

这个也是醉了。

大家如果收发SOAP消息,还是不要手工拼接这样写的好啊。

SUN PKIX、AXIS2及C#在HTTPS认证方式的区别

最近尝试了用两级自签名证书来验证SUN PKIX、AXIS2及C#在HTTPS认证方式的区别。
两级证书为:
1、CA证书NMyCA1024
2、服务器证书serversigned

其中,AXIS2通过验证是最简单的,
1、服务端设置serversigned证书的Key Store
2、客户端设置NMyCA1024或serversigned的Trust Store
3、通过验证。

如果要SUN PKIX通过验证(Oracle的JDK/JRE自带)
1、那需要服务端设置serversigned证书的Key Store
2、客户端设置NMyCA1024或serversigned的Trust Store
3、客户端把NMyCA1024证书导入JDK或JRE的CA证书列表cacerts
4、通过验证。

如果要C#通过验证
1、那需要服务端设置serversigned证书的P12文件
2、客户端设置NMyCA1024或serversigned的Trust Store
3、客户端双击NMyCA1024证书导入IE的CA证书列表
4、通过验证。

处理windows控制字符0x17

今天同事遇到了很诡异的问题,就是从数据库中读取一个字段时,有些数据中,会多一个0x17的控制字符。

暂时没太好的处理方法,自己写了个测试例子,仅供参考吧:

for java

    public static void main(String[] args)
    {
        byte[] b= { 0x30, 0x30, 0x1f, 0x37, 0x39, 0x33, 0x39, 0x36, 0x34, 0x31 };
        byte[] bt={0x1f};
        String s1 = new String(b);
        String st= new String(bt);
        String s2 = s1.replace(st,"");
        String s3 = s1.replace((char)0x1f,' ').replace(" ","");
        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s3);
    }

for charp

        static void Main(string[] args)
        {
            Byte[] b = { 0x30, 0x30, 0x1f, 0x37, 0x39, 0x33, 0x39, 0x36, 0x34, 0x31 };
            Byte[] bt = {0x1f};
            String s1 = System.Text.Encoding.Default.GetString(b);
            String st = System.Text.Encoding.Default.GetString(bt);
            String s2 = s1.Replace(st, "");
            String s3 = s1.Replace((char) (0x1F), ' ').Replace(" ", "");
            Console.WriteLine(s1);
            Console.WriteLine(s2);
            Console.WriteLine(s3);
            Console.ReadLine();
        }

Redis与Tomcat集群集成

在网站访问量急剧上升时,通常需要使用集群的方法进行横向扩展。
对于没有状态的应用来说,直接用nginx进行处理即可。
但对于有状态的应用来说,比如登录状态等,除了使用nginx进行扩展外,就需要考虑到Session共享的问题了。

大家知道可以用apache+tomcat来实现Session共享,但效率太低了,而且容易出错。
今天说的主要是用nginx+tomcat+redis+tomcat-redis-session-manager的方式实现共享。
原理比较简单:

1、tomcat-redis-session-manage扩展了
org.apache.catalina.valves.ValveBase;
org.apache.catalina.session.ManagerBase;
org.apache.catalina.session.StandardSession;
并通过Tomcat配置,替代了这几个类。

2、Set属性时,用session id作为key,将Tomcat的整个Session拆分为SessionSerializationMetadata+RedisSession然后序列化为byte[],存放到Redis。

3、Get属性时,用session id作为key,从Redis获取byte[],然后反序列化为SessionSerializationMetadata+RedisSession,供Tomcat使用。

配置也很简单:
1、从github下载源码tomcat-redis-session-manager

2、用gradle进行编译

#master分支下面,要把signing段和uploadArchives段删掉,才能正常编译
#release就不需要了
gradle build

3、将三个Jar包拷贝到Tomcat的lib文件夹下

#%TOMCAT_HOME%/lib
tomcat-redis-session-manager-master-2.0.0.jar
commons-pool2-2.2.jar
jedis-2.5.2.jar

4、修改context.xml配置文件,新增下面内容就搞定咯

<!--%TOMCAT_HOME%/conf/context.xml-->
  <Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
  <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager" 
  host="localhost" port="6379" database="0" maxInactiveInterval="60"/>

好处是:不需要修改应用
坏处是:要耗费一定的时间来(序列化+保存到Redis)、(反序列化+从Redis读取)。

DBUS发送接收数据(下)

1、编译后,由于没有进行配置,默认是无法运行的。
为了可以正常运行,增加或修改下面的配置文件即可。
/etc/dbus-1.0/system-local.conf

<!-- This configuration file controls the systemwide message bus.
     Add a system-local.conf and edit that rather than changing this 
     file directly. -->

<!-- Note that there are any number of ways you can hose yourself
     security-wise by screwing up this file; in particular, you
     probably don't want to listen on any more addresses, add any more
     auth mechanisms, run as a different user, etc. -->

<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>

  <!-- Our well-known bus type, do not change this -->
  <type>system</type>

  <!-- Run as special user -->
  <user>messagebus</user>

  <!-- Fork into daemon mode -->
  <fork/>

  <!-- We use system service launching using a helper -->
  <standard_system_servicedirs/>

  <!-- This is a setuid helper that is used to launch system services -->
  <servicehelper>/usr/lib/dbus-1.0/dbus-daemon-launch-helper</servicehelper>

  <!-- Write a pid file -->
  <pidfile>/var/run/dbus/pid</pidfile>

  <!-- Enable logging to syslog -->
  <syslog/>

  <!-- Only allow socket-credentials-based authentication -->
  <auth>EXTERNAL</auth>

  <!-- Only listen on a local socket. (abstract=/path/to/socket 
       means use abstract namespace, don't really create filesystem 
       file; only Linux supports this. Use path=/whatever on other 
       systems.) -->
  <listen>unix:path=/var/run/dbus/system_bus_socket</listen>

  <policy context="default">
    <!-- All users can connect to system bus -->
    <allow user="*"/>

    <!-- Holes must be punched in service configuration files for
         name ownership and sending method calls -->
    <allow own="*"/>
    <allow send_type="method_call"/>

    <!-- Signals and reply messages (method returns, errors) are allowed
         by default -->
    <allow send_type="signal"/>
    <allow send_requested_reply="true" send_type="method_return"/>
    <allow send_requested_reply="true" send_type="error"/>

    <!-- All messages may be received by default -->
    <allow receive_type="method_call"/>
    <allow receive_type="method_return"/>
    <allow receive_type="error"/>
    <allow receive_type="signal"/>

    <!-- Allow anyone to talk to the message bus -->
    <allow send_destination="org.freedesktop.DBus"/>
    <!-- But disallow some specific bus services -->
    <deny send_destination="org.freedesktop.DBus"
          send_interface="org.freedesktop.DBus"
          send_member="UpdateActivationEnvironment"/>
    <deny send_destination="org.freedesktop.DBus"
          send_interface="org.freedesktop.systemd1.Activator"/>
  </policy>

  <!-- Only systemd, which runs as root, may report activation failures. -->
  <policy user="root">
    <allow send_destination="org.freedesktop.DBus"
           send_interface="org.freedesktop.systemd1.Activator"/>
  </policy>

  <!-- Config files are placed here that among other things, punch 
       holes in the above policy for specific services. -->
  <includedir>system.d</includedir>

  <include if_selinux_enabled="yes" selinux_root_relative="yes">contexts/dbus_contexts</include>

</busconfig>

2、测试消息发送
服务端:

$./testdbus_s.bin receive
Listening for signals
Match rule sent
Got Signal with value: Hello
Got Signal with value: Hi
Bye......

客户端:

$./testdbus_s.bin send Hello
Sending signal with value: Hello
Signal Sent

$./testdbus_s.bin send Hi
Sending signal with value: Hi
Signal Sent

$./testdbus_s.bin send Bye
Sending signal with value: Bye
Signal Sent

3、测试方法调用
服务端:

$./testdbus_s.bin listen
Listening for method calls
Method Invoked with value: Hello
Method Invoked with value: Hi
Bye......

客户端:

$./testdbus_s.bin query Hello
Calling remote method with Hello
Request Sent
Got Reply: 1, 21614

$./testdbus_s.bin query Hi
Calling remote method with Hi
Request Sent
Got Reply: 1, 21614

$./testdbus_s.bin query Bye
Calling remote method with Bye
Request Sent
Got Reply: 1, 21614

DBUS发送接收数据(上)

1、Server端
testdbus_s.c

#define DBUS_API_SUBJECT_TO_CHANGE
#include <dbus/dbus.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

/**
 * Wait for signals on the bus and reply
 */
void receive()
{
  DBusMessage* msg;
  DBusMessageIter args;
  DBusConnection* conn;
  DBusError err;
  int ret;
  char* sigvalue;
  int loop=1;

  printf("Listening for signals\n");

  // initialise the errors
  dbus_error_init(&err);
  
  // connect to the bus and check for errors
  conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
  if (dbus_error_is_set(&err)) { 
     fprintf(stderr, "Connection Error (%s)\n", err.message);
     dbus_error_free(&err); 
  }
  if (NULL == conn) { 
     exit(1);
  }
  
  // request our name on the bus and check for errors
  ret = dbus_bus_request_name(conn, "neohope.dbus.signal.target", DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
  if (dbus_error_is_set(&err)) { 
     fprintf(stderr, "Name Error (%s)\n", err.message);
     dbus_error_free(&err); 
  }
  if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
     exit(1);
  }

  // add a rule for which messages we want to see
  dbus_bus_add_match(conn, "type='signal',interface='neohope.dbus.signal.Type'", &err); // see signals from the given interface
  dbus_connection_flush(conn);
  if (dbus_error_is_set(&err)) { 
     fprintf(stderr, "Match Error (%s)\n", err.message);
     exit(1); 
  }
  printf("Match rule sent\n");

  // loop listening for signals being emmitted
  while (loop) {

     // non blocking read of the next available message
     dbus_connection_read_write(conn, 0);
     msg = dbus_connection_pop_message(conn);

     // loop again if we haven't read a message
     if (NULL == msg) { 
        sleep(1);
        continue;
     }

     // check if the message is a signal from the correct interface and with the correct name
     if (dbus_message_is_signal(msg, "neohope.dbus.signal.Type", "TestSignal")) {
        
        // read the parameters
        if (!dbus_message_iter_init(msg, &args))
           fprintf(stderr, "Message Has No Parameters\n");
        else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) 
           fprintf(stderr, "Argument is not string!\n"); 
        else
           dbus_message_iter_get_basic(&args, &sigvalue);
        
        if(strcmp("Bye",sigvalue)==0) {
           loop = 0;
           printf("Bye......\n");
        }
        else {
          printf("Got Signal with value: %s\n", sigvalue);
        }
     }

     // free the message
     dbus_message_unref(msg);
  }
  // do not close the connection
  // dbus_connection_close(conn);
}

/**
 * Deal with remote method call 
 */
int reply_to_method_call(DBusMessage* msg, DBusConnection* conn)
{
  DBusMessage* reply;
  DBusMessageIter args;
  int stat = 1;
  int ret = 1;
  dbus_uint32_t level = 21614;
  dbus_uint32_t serial = 0;
  char* param = "";

  // read the arguments
  if (!dbus_message_iter_init(msg, &args))
     fprintf(stderr, "Message has no arguments!\n"); 
  else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) 
     fprintf(stderr, "Argument is not string!\n"); 
  else 
     dbus_message_iter_get_basic(&args, &param);

  if(strcmp("Bye",param)==0){
    ret = 0;
    printf ("Bye......\n");
  }
  else {
    printf("Method Invoked with value: %s\n", sigvalue);
  }

  // create a reply from the message
  reply = dbus_message_new_method_return(msg);

  // add the arguments to the reply
  dbus_message_iter_init_append(reply, &args);
  if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_BOOLEAN, &stat)) { 
     fprintf(stderr, "Out Of Memory!\n"); 
     exit(1);
  }
  if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &level)) { 
     fprintf(stderr, "Out Of Memory!\n"); 
     exit(1);
  }

  // send the reply && flush the connection
  if (!dbus_connection_send(conn, reply, &serial)) {
     fprintf(stderr, "Out Of Memory!\n"); 
     exit(1);
  }
  dbus_connection_flush(conn);

  // free the reply
  dbus_message_unref(reply);
  
  return ret;
}

/**
 * Server that exposes a method call and waits for it to be called
 */
void listen() 
{
  DBusMessage* msg;
  DBusMessage* reply;
  DBusMessageIter args;
  DBusConnection* conn;
  DBusError err;
  int loop = 1;
  int ret;
  char* param;

  printf("Listening for method calls\n");

  // initialise the error
  dbus_error_init(&err);
  
  // connect to the bus and check for errors
  conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
  if (dbus_error_is_set(&err)) { 
     fprintf(stderr, "Connection Error (%s)\n", err.message); 
     dbus_error_free(&err); 
  }
  if (NULL == conn) {
     fprintf(stderr, "Connection Null\n"); 
     exit(1); 
  }
  
  // request our name on the bus and check for errors
  ret = dbus_bus_request_name(conn, "neohope.dbus.method.provider", DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
  if (dbus_error_is_set(&err)) { 
     fprintf(stderr, "Name Error (%s)\n", err.message); 
     dbus_error_free(&err);
  }
  if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { 
     fprintf(stderr, "Not Primary Owner (%d)\n", ret);
     exit(1); 
  }

  // loop, testing for new messages
  while (loop) {
     // non blocking read of the next available message
     dbus_connection_read_write(conn, 0);
     msg = dbus_connection_pop_message(conn);

     // loop again if we haven't got a message
     if (NULL == msg) { 
        sleep(1); 
        continue; 
     }
     
     // check this is a method call for the right interface & method
     if (dbus_message_is_method_call(msg, "neohope.dbus.method.Type", "TestMethod")) 
        loop = reply_to_method_call(msg, conn);

     // free the message
     dbus_message_unref(msg);
  }

  // do not close the connection
  // dbus_connection_close(conn);
}

int main(int argc, char** argv)
{
  if (2 > argc) {
     printf ("Syntax: testdbus_s [receive|listen] [<param>]\n");
     return 1;
  }
  char* param = "no param";
  if (3 >= argc && NULL != argv[2]) param = argv[2];

  if (0 == strcmp(argv[1], "receive"))
     receive();
  else if (0 == strcmp(argv[1], "listen"))
     listen();
  else {
     printf ("Syntax: testdbus_s [receive|listen] [<param>]\n");
     return 1;
  }
  return 0;
}

2、Client端
testdbus_c.c

#define DBUS_API_SUBJECT_TO_CHANGE
#include <dbus/dbus.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

/**
 * Connect to the DBUS bus and send a broadcast signal
 */
void sendsignal(char* sigvalue)
{
  DBusMessage* msg;
  DBusMessageIter args;
  DBusConnection* conn;
  DBusError err;
  int ret;
  dbus_uint32_t serial = 0;

  printf("Sending signal with value: %s\n", sigvalue);

  // initialise the error value
  dbus_error_init(&err);

  // connect to the DBUS system bus, and check for errors
  conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
  if (dbus_error_is_set(&err)) { 
     fprintf(stderr, "Connection Error (%s)\n", err.message); 
     dbus_error_free(&err); 
  }
  if (NULL == conn) { 
     exit(1); 
  }

  // register our name on the bus, and check for errors
  ret = dbus_bus_request_name(conn, "neohope.dbus.signal.source", DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
  if (dbus_error_is_set(&err)) { 
     fprintf(stderr, "Name Error (%s)\n", err.message); 
     dbus_error_free(&err); 
  }
  if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { 
     exit(1);
  }

  // create a signal & check for errors 
  msg = dbus_message_new_signal("/neohope/dbus/signal/Object", // object name of the signal
                                "neohope.dbus.signal.Type", // interface name of the signal
                                "TestSignal"); // name of the signal
  if (NULL == msg) 
  { 
     fprintf(stderr, "Message Null\n"); 
     exit(1); 
  }

  // append arguments onto signal
  dbus_message_iter_init_append(msg, &args);
  if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &sigvalue)) {
     fprintf(stderr, "Out Of Memory!\n"); 
     exit(1);
  }

  // send the message and flush the connection
  if (!dbus_connection_send(conn, msg, &serial)) {
     fprintf(stderr, "Out Of Memory!\n"); 
     exit(1);
  }
  dbus_connection_flush(conn);
  
  printf("Signal Sent\n");
  
  // free the message
  dbus_message_unref(msg);
  // do not close the connection
  // dbus_connection_close(conn);
}

/**
 * Call a method on a remote object
 */
void query(char* param) 
{
  DBusMessage* msg;
  DBusMessageIter args;
  DBusConnection* conn;
  DBusError err;
  DBusPendingCall* pending;
  int ret;
  int stat;
  dbus_uint32_t level;

  printf("Calling remote method with %s\n", param);

  // initialiset the errors
  dbus_error_init(&err);

  // connect to the system bus and check for errors
  conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
  if (dbus_error_is_set(&err)) { 
     fprintf(stderr, "Connection Error (%s)\n", err.message); 
     dbus_error_free(&err);
  }
  if (NULL == conn) { 
     exit(1); 
  }

  // request our name on the bus
  ret = dbus_bus_request_name(conn, "neohope.dbus.method.caller", DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
  if (dbus_error_is_set(&err)) { 
     fprintf(stderr, "Name Error (%s)\n", err.message); 
     dbus_error_free(&err);
  }
  if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { 
     exit(1);
  }

  // create a new method call and check for errors
  msg = dbus_message_new_method_call("neohope.dbus.method.provider", // target for the method call
                                     "/neohope/dbus/method/Object", // object to call on
                                     "neohope.dbus.method.Type", // interface to call on
                                     "TestMethod"); // method name
  if (NULL == msg) { 
     fprintf(stderr, "Message Null\n");
     exit(1);
  }

  // append arguments
  dbus_message_iter_init_append(msg, &args);
  if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &param)) {
     fprintf(stderr, "Out Of Memory!\n"); 
     exit(1);
  }
  
  // send message and get a handle for a reply
  if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) { // -1 is default timeout
     fprintf(stderr, "Out Of Memory!\n"); 
     exit(1);
  }
  if (NULL == pending) { 
     fprintf(stderr, "Pending Call Null\n"); 
     exit(1); 
  }
  dbus_connection_flush(conn);
  
  printf("Request Sent\n");
  
  // free message
  dbus_message_unref(msg);
  
  // block until we recieve a reply
  dbus_pending_call_block(pending);

  // get the reply message
  msg = dbus_pending_call_steal_reply(pending);
  if (NULL == msg) {
     fprintf(stderr, "Reply Null\n"); 
     exit(1); 
  }
  // free the pending message handle
  dbus_pending_call_unref(pending);

  // read the parameters
  if (!dbus_message_iter_init(msg, &args))
     fprintf(stderr, "Message has no arguments!\n"); 
  else if (DBUS_TYPE_BOOLEAN != dbus_message_iter_get_arg_type(&args)) 
     fprintf(stderr, "Argument is not boolean!\n"); 
  else
     dbus_message_iter_get_basic(&args, &stat);

  if (!dbus_message_iter_next(&args))
     fprintf(stderr, "Message has too few arguments!\n"); 
  else if (DBUS_TYPE_UINT32 != dbus_message_iter_get_arg_type(&args)) 
     fprintf(stderr, "Argument is not int!\n"); 
  else
     dbus_message_iter_get_basic(&args, &level);

  printf("Got Reply: %d, %d\n", stat, level);
  
  // free reply and close connection
  dbus_message_unref(msg);   
  //dbus_connection_close(conn);
}

int main(int argc, char** argv)
{
  if (2 > argc) {
     printf ("Syntax: testdbus_c [send|query] [<param>]\n");
     return 1;
  }
  char* param = "no param";
  if (3 >= argc && NULL != argv[2]) param = argv[2];

  if (0 == strcmp(argv[1], "send"))
     sendsignal(param);
  else if (0 == strcmp(argv[1], "query"))
     query(param);
  else {
     printf ("Syntax: testdbus_c [send|query] [<param>]\n");
     return 1;
  }
  return 0;
}

3、Makefile

CC=gcc
LDFLAGS+=-ldbus-1
CFLAGS+=-I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include/

all:testdbus_c.bin testdbus_s.bin

testdbus_c.bin:testdbus_c.o
	$(CC) $(LDFLAGS) -o testdbus_c.bin testdbus_c.o 

testdbus_c.o:testdbus_c.c
	$(CC) $(CFLAGS) -c -o testdbus_c.o testdbus_c.c 

testdbus_s.bin:testdbus_s.o
	$(CC) $(LDFLAGS) -o testdbus_s.bin testdbus_s.o 

testdbus_s.o:testdbus_s.c
	$(CC) $(CFLAGS) -c -o testdbus_s.o testdbus_s.c 

clean:
	rm *.o *.bin

4、编译

make

CMD常用命令17常用软件注册为Widows服务

1、Apache注册为Widows服务

httpd -k install

2、MySQL注册为Widows服务

mysqld --install MySQL --defaults-file="D:\MySQL\MySQL Server 5.1\my.ini"

3、PostgreSQL注册为Widows服务

pg_ctl.exe register -N "postgresql-8.4" -D "D:/PostgreSQL/8.4/data" -w

4、SVN注册为Widows服务

sc create svnserve binPath= "\"D:\Subversion\bin\svnserve.exe\" --service -r \"D:\Subversion\repository\"" displayname= "Subversion Service" depend= Tcpip start= auto 
sc start svnserve 
sc stop svnserve 
sc delete svnserve

5、redis注册为Widows服务

#loglevel 分为debug, notice, warning三级
redis-server.exe --service-install D:\Database\Redis2.8\db\redis.windows.conf --loglevel notice
redis-server --service-start
redis-server --service-stop
redis-server --service-uninstall

6、mongodb注册为Widows服务

mongod --dbpath=D:\Database\MongoDB3\db --logpath=D:\Database\MongoDB3\log\mongo.log --port 27027 --noauth --install -serviceName MongoDB01 --serviceDisplayName MongoDB01 
net start MongoDB01

FreeBSD10安装开发环境

1、安装JDK
1.1、Oracle没有为FreeBSD提供JDK环境,自带版本也挺高,那就安装默认的咯

pkg install jdk8

*在windows下编译过,超级大,时间也很久,实在不想编译openjdk了。

1.2、修改/etc/fstab文件,增加下面两行,搞定

# Device	Mountpoint	FStype	Options	Dump	Pass#
/dev/ada0p2	/		ufs	rw	1	1
/dev/ada0p3	none		swap	sw	0	0
fdesc		/dev/fd		fdescfs	rw	0	0
proc		/proc		procfs	rw	0	0

2、自己编译Ruby,当然也可以用pkg安装
2.1、下载并编译源码
ruby-lang.org

./configure --prefix=usr/ruby/ruby_2.2.3
make
make install

2.2、配置环境变量,默认为csh
编辑~/.cshrc

set RUBY_HOME=/usr/ruby/ruby_2.2.3
set path=($RUBY_HOME/bin $path)

重新登录一下。

2.3、切换为国内源

gem sources --add https://ruby.taobao.org/
gem sources --remove https://rubygems.org/
gem sources -l

2.4、安装gems

$ gem install rails
$ gem install redis

3、自己编译redis,当然也可以用pkg安装
3.1、下载并编译源码
redis.io

pkg install gmake
gmake
gmake PREFIX=/usr/redis/redis_3.0.4 install

3.2、配置环境变量,默认为csh
编辑~/.cshrc

set REDIS_HOME=/usr/redis/redis_3.0.4
set path=($REDIS_HOME/bin $path)

重新登录一下。

4、安装mongodb
4.1、下载并编译源码
mongodb.org

pkg install gcc
pkg install scons
pkg install python
pkg install libexecinfo

scons all
scons --prefix=/usr/mongodb/mongodb_3.0.7 install

*顺便说一下,这个编译后是18G,安装后为1.1G。。。
*如果你用的是3.0.7版本的源码,在FreeBSD下需要打补丁
github.com

4.2、配置环境变量,默认为csh
编辑~/.cshrc

set MONGODB_HOME=/usr/mongodb/mongodb_3.0.7
set path=($MONGODB_HOME/bin $path)

重新登录一下。

Virtualbox安装配置FreeBSD10

1、新建虚拟机,下载DVD镜像文件,安装虚拟机,整个过程比较简单:分区,选择需要的包,配置网络,配置用户
其中,我的虚拟机网卡配置为:
le0 是hostonly,用于与宿主机、其他虚拟机进行网络通许,要手工设置
le1 是nat,用于蹭网,设置为DHCP就好了

2、安装后重启,发现新用户不能su,将新用户添加到wheel组

#此命令一如既往的强大
bsdconfig

3、然后发现,le1发现可以连外网,但le0配置有些问题,编辑/etc/rc.conf

#network config
hostname="freebsd10"
ifconfig_le0="inet 172.16.172.5 netmask 255.255.0.0"
ifconfig_le1="DHCP"
ip6addrctl_enable="NO"
defaultrouter="10.0.3.2"
#static_routes="net1"
#route_net1="-net 172.16.172.0/16 172.16.172.1"

重启网络,OK。

4、找了一下,VirtualBox自带的扩展插件是没有BSD系统支持的,那就安装开源的呗
首先尝试了bsdconfig进行安装,但系统提示找不到数据库

bsdconfig
#选择Packages
no pkg(8) database found.

4.1A网上找了下,从DVD安装可以这样处理:

mount -t cd9660 /dev/cd0 /dist
env REPOS_DIR=/dist/packages/repos pkg search virtualbox
env REPOS_DIR=/dist/packages/repos pkg install virtualbox-ose-additions 

4.1B或者,直接采用网络安装可以这样处理:

pkg install virtualbox-ose-additions 

4.2安装后,需要在/etc/rc.conf中增加

vboxguest_enable=“YES”
vboxservice_enable=“YES”

重启

5、安装图形界面
从DVD安装可以这样处理:
5.1A

mount -t cd9660 /dev/cd0 /dist

env REPOS_DIR=/dist/packages/repos pkg search xorg
env REPOS_DIR=/dist/packages/repos pkg install xorg

env REPOS_DIR=/dist/packages/repos pkg search gnome
env REPOS_DIR=/dist/packages/repos pkg install gnome3

5.1B或者,直接采用网络安装可以这样处理:

pkg install xorg
pkg install gnome3

5.2A安装完毕后,如果想重启后直接进入图形界面,需要在/etc/rc.conf中增加

gdm_enable="YES"
gnome_enable="YES"

5.2B如果想重启后进入命令行界面,需要在/etc/rc.conf中增加

dbus_enable="YES"

然后,执行命令

echo exec gnome-session > ~/.xinitrc
startx

6、发现命令行界面分辨率太低
6.1查看系统支持的分辨率

#列出所有支持的分辨率
vidcontrol -i mode
#尝试1024x768x24
vidcontrol MODE_280

6.2在/etc/rc.conf中增加

allscreens_flags="MODE_280"

7、启动后,发现sendmail服务启动耗时很久,反正用不到,编辑/etc/rc.conf文件,禁用之

vi /etc/rc.conf
sendmail_enable="NONE"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"

8、最终,我的/etc/rc.conf文件如下

#network config
hostname="freebsd10"
ifconfig_le0="inet 172.16.172.5 netmask 255.255.0.0"
ifconfig_le1="DHCP"
ip6addrctl_enable="NO"
defaultrouter="10.0.3.2"
#static_routes="net1"
#route_net1="-net 172.16.172.0/16 172.16.172.1"

#display config
vboxguest_enable="YES"
vboxservice_enable="YES"
allscreens_flags="MODE_280"
#gdm_enable="YES"
#gnome_enable="YES"

#other service config
sshd_enable="YES"
powerd_enable="YES"
moused_enable="YES"
dbus_enable="YES"

#"AUTO" to enable crash dumps, "NO" to disable crash dumps
dumpdev="AUTO"

#disapbled service
zfs_enable="NO"
sendmail_enable="NONE"
sendmail_outbound_enbale="NO"
sendmail_msp_queue_enable="NO"
sendmail_submit_enable="NO"