This commit is contained in:
地平线
2015-04-17 16:57:02 +08:00
parent bba2766ee9
commit 282081cf95
9 changed files with 63 additions and 58 deletions

View File

@@ -14,8 +14,9 @@
<!-- <!--
远程client地址组资源. 注意: remote的name值不能为LOCAL不区分大小写 远程client地址组资源. 注意: remote的name值不能为LOCAL不区分大小写
protocol 值只能是UDP TCP 默认UDP protocol 值只能是UDP TCP 默认UDP
group: 组名, 默认是空字符串, 通常不同机房使用不同的group值
--> -->
<remote name="mygroup" protocol="UDP"> <remote name="myremote" protocol="UDP" group="">
<!-- <!--
weight: 权重百分比。 不指定则平均。 weight之和必须<=100 weight: 权重百分比。 不指定则平均。 weight之和必须<=100
[注: weight尚未实现] [注: weight尚未实现]
@@ -67,7 +68,7 @@
加载所有的Service服务; 加载所有的Service服务;
在同一个进程中所有LOCAL模式的Service 同一个name的将共用同一个实例 在同一个进程中所有LOCAL模式的Service 同一个name的将共用同一个实例
autoload="true" 默认值. 自动加载以下目录如果存在的话下所有的Service类: autoload="true" 默认值. 自动加载以下目录如果存在的话下所有的Service类:
server.lib; server.root/lib/*; server.root/classes; server.lib; server.lib/*; server.classes;
autoload="false" 需要显著的指定Service类 autoload="false" 需要显著的指定Service类
includes 当autoload="true" 拉取类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开 includes 当autoload="true" 拉取类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
excludes 当autoload="true" 排除类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开 excludes 当autoload="true" 排除类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
@@ -75,7 +76,7 @@
当<services>指定remote值为非空非LOCAL(即远程模式)时, 所有service的remote值均默认是<services>指定remote值。 当<services>指定remote值为非空非LOCAL(即远程模式)时, 所有service的remote值均默认是<services>指定remote值。
当<services>指定remote值为空(即本地模式)时, 所有service的remote值均默认是LOCAL值。 当<services>指定remote值为空(即本地模式)时, 所有service的remote值均默认是LOCAL值。
--> -->
<services autoload="true" includes="" excludes="" remote="mygroup"> <services autoload="true" includes="" excludes="" remote="myremote">
<!-- <!--
大部分的情况下, 存在多个节点环境中很多service节点配置都一致为此提供group节点来方便配置。 大部分的情况下, 存在多个节点环境中很多service节点配置都一致为此提供group节点来方便配置。
remotenames: 远程模式Service的name名称集合 多个用分号;隔开, 名称必须是在resources节点中定义的remote节点。 remotenames: 远程模式Service的name名称集合 多个用分号;隔开, 名称必须是在resources节点中定义的remote节点。
@@ -86,8 +87,8 @@
<service value="com.xxx.XXX0Service" name="RT003" remote="RT003"/> <service value="com.xxx.XXX0Service" name="RT003" remote="RT003"/>
--> -->
<group remotenames="RT001;RT002;RT003"> <group remotenames="RT001;RT002;RT003">
<service value="com.xxx.XXX0Service"/> <service value="com.xxx.XXX0Service"/>
</group> </group>
<!-- 显著加载指定的Service的接口类 --> <!-- 显著加载指定的Service的接口类 -->
<service value="com.xxx.XXX1Service"/> <service value="com.xxx.XXX1Service"/>
@@ -98,6 +99,29 @@
--> -->
<service value="com.xxx.XXX2Service" name="" remote="LOCAL"/> <service value="com.xxx.XXX2Service" name="" remote="LOCAL"/>
</services> </services>
<!--
当Server为HTTP、HTTPS协议时, request节点才有效。
remoteaddr 节点: 替换请求方节点的IP地址 通常请求方是由nginx等web静态服务器转发过的则需要配置该节点。
且value值只能是以request.headers.开头表示从request.headers中获取对应的header值。
例如下面例子获取request.getRemoteAddr()值如果header存在X-RemoteAddress值则返回X-RemoteAddress值不存在返回request.getRemoteAddress()。
-->
<request>
<remoteaddr value="request.headers.X-RemoteAddress"/>
</request>
<!--
当Server为HTTP、HTTPS协议时, response节点才有效。
defcookie 节点: 当response里输出的cookie没有指定domain 和path时使用该节点的默认值。
如果addheader、setheader 的value值以request.headers.开头则表示从request.headers中获取对应的header值
例如下面例子是在Response输出header时添加两个header一个addHeader 一个setHeader
-->
<response>
<defcookie domain="" path=""/>
<addheader name="Access-Control-Allow-Origin" value="request.headers.Origin" />
<setheader name="Access-Control-Allow-Credentials" value="true"/>
</response>
<!-- <!--
加载所有的Servlet服务; 加载所有的Servlet服务;
prefix: servlet的ContextPath前缀 默认为空 prefix: servlet的ContextPath前缀 默认为空
@@ -105,11 +129,11 @@
${APP_HOME}/lib; ${APP_HOME}/root/lib/*; ${APP_HOME}/root/classes; ${APP_HOME}/lib; ${APP_HOME}/root/lib/*; ${APP_HOME}/root/classes;
autoload="false" 需要显著的指定Service类 autoload="false" 需要显著的指定Service类
includes 当autoload="true" 拉取类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开 includes 当autoload="true" 拉取类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
excludes 当autoload="true" 排除类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开 excludes 当autoload="true" 排除类名与excludes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
--> -->
<servlets prefix="/pipes" autoload="true" includes="" excludes=""> <servlets prefix="/pipes" autoload="true" includes="" excludes="">
<!-- <!--
当Server为HTTP、HTTP协议时ResourceServlet才有效. 默认存在一个有默认属性的resource-servlet节点 当Server为HTTP、HTTPS协议时ResourceServlet才有效. 默认存在一个有默认属性的resource-servlet节点
webroot: web资源的根目录 默认取server节点中的root值 webroot: web资源的根目录 默认取server节点中的root值
--> -->
<resource-servlet webroot="root"> <resource-servlet webroot="root">

View File

@@ -93,7 +93,7 @@ public final class Application {
private final long startTime = System.currentTimeMillis(); private final long startTime = System.currentTimeMillis();
private CountDownLatch cdl; private CountDownLatch serverscdl;
private Application(final AnyValue config) { private Application(final AnyValue config) {
this.config = config; this.config = config;
@@ -203,7 +203,7 @@ public final class Application {
final Application application = Application.create(); final Application application = Application.create();
application.init(); application.init();
application.factory.register(service); application.factory.register(service);
new NodeHttpServer(application, new CountDownLatch(1), null).load(application.config); new NodeHttpServer(application, new CountDownLatch(1), null).prepare(application.config);
application.factory.inject(service); application.factory.inject(service);
} }
@@ -240,6 +240,7 @@ public final class Application {
try { try {
final DatagramChannel channel = DatagramChannel.open(); final DatagramChannel channel = DatagramChannel.open();
channel.configureBlocking(true); channel.configureBlocking(true);
channel.socket().setSoTimeout(3000);
channel.bind(new InetSocketAddress(config.getValue("host", "127.0.0.1"), config.getIntValue("port"))); channel.bind(new InetSocketAddress(config.getValue("host", "127.0.0.1"), config.getIntValue("port")));
boolean loop = true; boolean loop = true;
ByteBuffer buffer = ByteBuffer.allocateDirect(1024); ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
@@ -254,14 +255,13 @@ public final class Application {
long s = System.currentTimeMillis(); long s = System.currentTimeMillis();
logger.info(application.getClass().getSimpleName() + " shutdowning"); logger.info(application.getClass().getSimpleName() + " shutdowning");
application.shutdown(); application.shutdown();
application.cdl.countDown();
buffer.clear(); buffer.clear();
buffer.put("SHUTDOWN OK".getBytes()); buffer.put("SHUTDOWN OK".getBytes());
buffer.flip(); buffer.flip();
channel.send(buffer, address); channel.send(buffer, address);
long e = System.currentTimeMillis() - s; long e = System.currentTimeMillis() - s;
logger.info(application.getClass().getSimpleName() + " shutdown in " + e + " ms"); logger.info(application.getClass().getSimpleName() + " shutdown in " + e + " ms");
Thread.sleep(100L); application.serverscdl.countDown();
System.exit(0); System.exit(0);
} catch (Exception ex) { } catch (Exception ex) {
logger.log(Level.INFO, "SHUTDOWN FAIL", ex); logger.log(Level.INFO, "SHUTDOWN FAIL", ex);
@@ -301,12 +301,12 @@ public final class Application {
public void start() throws Exception { public void start() throws Exception {
final AnyValue[] entrys = config.getAnyValues("server"); final AnyValue[] entrys = config.getAnyValues("server");
cdl = new CountDownLatch(entrys.length + 1); this.serverscdl = new CountDownLatch(entrys.length + 1);
CountDownLatch timecd = new CountDownLatch(entrys.length); CountDownLatch timecd = new CountDownLatch(entrys.length);
runServers(timecd, entrys); runServers(timecd, entrys);
timecd.await(); timecd.await();
logger.info(this.getClass().getSimpleName() + " started in " + (System.currentTimeMillis() - startTime) + " ms"); logger.info(this.getClass().getSimpleName() + " started in " + (System.currentTimeMillis() - startTime) + " ms");
cdl.await(); this.serverscdl.await();
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -337,14 +337,13 @@ public final class Application {
} }
servers.add(server); servers.add(server);
server.load(entry); //必须在init之前 server.prepare(entry); //必须在init之前
server.init(entry); server.init(entry);
server.start(); server.start();
timecd.countDown(); timecd.countDown();
} catch (Exception ex) { } catch (Exception ex) {
logger.log(Level.WARNING, entry + " runServers error", ex); logger.log(Level.WARNING, entry + " runServers error", ex);
} finally { serverscdl.countDown();
cdl.countDown();
} }
} }
}.start(); }.start();
@@ -519,11 +518,11 @@ public final class Application {
} catch (Exception t) { } catch (Exception t) {
logger.log(Level.WARNING, " shutdown server(" + server.getSocketAddress() + ") error", t); logger.log(Level.WARNING, " shutdown server(" + server.getSocketAddress() + ") error", t);
} finally { } finally {
cdl.countDown(); serverscdl.countDown();
} }
}); });
final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null; final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
localServices.entrySet().parallelStream().forEach(k -> { localServices.entrySet().stream().forEach(k -> {
Class x = k.getKey(); Class x = k.getKey();
ServiceEntry y = k.getValue(); ServiceEntry y = k.getValue();
long s = System.currentTimeMillis(); long s = System.currentTimeMillis();

View File

@@ -42,8 +42,8 @@ public final class NodeHttpServer extends NodeServer {
} }
@Override @Override
public void load(AnyValue config) throws Exception { public void prepare(AnyValue config) throws Exception {
super.load(config); super.prepare(config);
ClassFilter<HttpServlet> httpFilter = createHttpServletClassFilter(application.nodeName, config); ClassFilter<HttpServlet> httpFilter = createHttpServletClassFilter(application.nodeName, config);
ClassFilter<Service> serviceFilter = createServiceClassFilter(application.nodeName, config); ClassFilter<Service> serviceFilter = createServiceClassFilter(application.nodeName, config);
long s = System.currentTimeMillis(); long s = System.currentTimeMillis();

View File

@@ -48,7 +48,7 @@ public abstract class NodeServer {
this.logger = Logger.getLogger(this.getClass().getSimpleName()); this.logger = Logger.getLogger(this.getClass().getSimpleName());
} }
public void load(final AnyValue config) throws Exception { public void prepare(final AnyValue config) throws Exception {
} }
public void init(AnyValue config) throws Exception { public void init(AnyValue config) throws Exception {

View File

@@ -37,8 +37,8 @@ public final class NodeSncpServer extends NodeServer {
} }
@Override @Override
public void load(AnyValue config) throws Exception { public void prepare(AnyValue config) throws Exception {
super.load(config); super.prepare(config);
ClassFilter<Service> serviceFilter = createServiceClassFilter(application.nodeName, config); ClassFilter<Service> serviceFilter = createServiceClassFilter(application.nodeName, config);
long s = System.currentTimeMillis(); long s = System.currentTimeMillis();
ClassFilter.Loader.load(application.getHome(), serviceFilter); ClassFilter.Loader.load(application.getHome(), serviceFilter);

View File

@@ -565,32 +565,28 @@ public final class DataJDBCSource implements DataSource {
public <T> void delete(Class<T> clazz, Serializable... ids) { public <T> void delete(Class<T> clazz, Serializable... ids) {
Connection conn = createWriteSQLConnection(); Connection conn = createWriteSQLConnection();
try { try {
if (ids != null && ids.length == 1 && ids[0] != null && ids[0].getClass().isArray()) {
Class clz = ids[0].getClass();
if (clz == long[].class) {
long[] vs = (long[]) ids[0];
ids = new Serializable[vs.length];
for (int i = 0; i < vs.length; i++) {
ids[i] = vs[i];
}
} else if (clz == int[].class) {
int[] vs = (int[]) ids[0];
ids = new Serializable[vs.length];
for (int i = 0; i < vs.length; i++) {
ids[i] = vs[i];
}
}
}
delete(conn, clazz, ids); delete(conn, clazz, ids);
} finally { } finally {
closeSQLConnection(conn); closeSQLConnection(conn);
} }
} }
@Override
public <T> void delete(Class<T> clazz, int[] ids) {
if (ids == null) return;
Serializable[] newids = new Serializable[ids.length];
for (int i = 0; i < ids.length; i++) {
newids[i] = ids[i];
}
delete(clazz, newids);
}
@Override
public <T> void delete(Class<T> clazz, long[] ids) {
if (ids == null) return;
Serializable[] newids = new Serializable[ids.length];
for (int i = 0; i < ids.length; i++) {
newids[i] = ids[i];
}
delete(clazz, newids);
}
/** /**
* 根据主键值删除对象, 必须是Entity Class * 根据主键值删除对象, 必须是Entity Class
* *

View File

@@ -59,16 +59,6 @@ final class DataJPASource implements DataSource {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
} }
@Override
public <T> void delete(Class<T> clazz, int[] ids) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public <T> void delete(Class<T> clazz, long[] ids) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
private static class DataJPAConnection extends DataConnection { private static class DataJPAConnection extends DataConnection {
private final EntityManager manager; private final EntityManager manager;

View File

@@ -83,10 +83,6 @@ public interface DataSource {
*/ */
public <T> void delete(Class<T> clazz, Serializable... ids); public <T> void delete(Class<T> clazz, Serializable... ids);
public <T> void delete(Class<T> clazz, int[] ids);
public <T> void delete(Class<T> clazz, long[] ids);
/** /**
* 根据主键值删除对象, 必须是Entity Class * 根据主键值删除对象, 必须是Entity Class
* *

View File

@@ -149,7 +149,7 @@ final class EntityCache<T> {
public void insert(T value) { public void insert(T value) {
if (value == null) return; if (value == null) return;
T rs = needcopy ? reproduce.copy(this.creator.create(), value) : value; //确保同一主键值的map与list中的对象必须共用。 T rs = reproduce.copy(this.creator.create(), value); //确保同一主键值的map与list中的对象必须共用。
T old = this.map.put((Serializable) this.primary.get(rs), rs); T old = this.map.put((Serializable) this.primary.get(rs), rs);
if (old != null) logger.log(Level.WARNING, "cache repeat insert data: " + value); if (old != null) logger.log(Level.WARNING, "cache repeat insert data: " + value);
this.list.add(rs); this.list.add(rs);