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不区分大小写
protocol 值只能是UDP TCP 默认UDP
group: 组名, 默认是空字符串, 通常不同机房使用不同的group值
-->
<remote name="mygroup" protocol="UDP">
<remote name="myremote" protocol="UDP" group="">
<!--
weight: 权重百分比。 不指定则平均。 weight之和必须<=100
[注: weight尚未实现]
@@ -67,7 +68,7 @@
加载所有的Service服务;
在同一个进程中所有LOCAL模式的Service 同一个name的将共用同一个实例
autoload="true" 默认值. 自动加载以下目录如果存在的话下所有的Service类:
server.lib; server.root/lib/*; server.root/classes;
server.lib; server.lib/*; server.classes;
autoload="false" 需要显著的指定Service类
includes 当autoload="true" 拉取类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
excludes 当autoload="true" 排除类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
@@ -75,7 +76,7 @@
当<services>指定remote值为非空非LOCAL(即远程模式)时, 所有service的remote值均默认是<services>指定remote值。
当<services>指定remote值为空(即本地模式)时, 所有service的remote值均默认是LOCAL值。
-->
<services autoload="true" includes="" excludes="" remote="mygroup">
<services autoload="true" includes="" excludes="" remote="myremote">
<!--
大部分的情况下, 存在多个节点环境中很多service节点配置都一致为此提供group节点来方便配置。
remotenames: 远程模式Service的name名称集合 多个用分号;隔开, 名称必须是在resources节点中定义的remote节点。
@@ -86,8 +87,8 @@
<service value="com.xxx.XXX0Service" name="RT003" remote="RT003"/>
-->
<group remotenames="RT001;RT002;RT003">
<service value="com.xxx.XXX0Service"/>
</group>
<service value="com.xxx.XXX0Service"/>
</group>
<!-- 显著加载指定的Service的接口类 -->
<service value="com.xxx.XXX1Service"/>
@@ -98,6 +99,29 @@
-->
<service value="com.xxx.XXX2Service" name="" remote="LOCAL"/>
</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服务;
prefix: servlet的ContextPath前缀 默认为空
@@ -105,11 +129,11 @@
${APP_HOME}/lib; ${APP_HOME}/root/lib/*; ${APP_HOME}/root/classes;
autoload="false" 需要显著的指定Service类
includes 当autoload="true" 拉取类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
excludes 当autoload="true" 排除类名与includes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
excludes 当autoload="true" 排除类名与excludes中的正则表达式匹配的类, 多个正则表达式用分号;隔开
-->
<servlets prefix="/pipes" autoload="true" includes="" excludes="">
<!--
当Server为HTTP、HTTP协议时ResourceServlet才有效. 默认存在一个有默认属性的resource-servlet节点
当Server为HTTP、HTTPS协议时ResourceServlet才有效. 默认存在一个有默认属性的resource-servlet节点
webroot: web资源的根目录 默认取server节点中的root值
-->
<resource-servlet webroot="root">

View File

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

View File

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

View File

@@ -48,7 +48,7 @@ public abstract class NodeServer {
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 {

View File

@@ -37,8 +37,8 @@ public final class NodeSncpServer extends NodeServer {
}
@Override
public void load(AnyValue config) throws Exception {
super.load(config);
public void prepare(AnyValue config) throws Exception {
super.prepare(config);
ClassFilter<Service> serviceFilter = createServiceClassFilter(application.nodeName, config);
long s = System.currentTimeMillis();
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) {
Connection conn = createWriteSQLConnection();
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);
} finally {
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
*

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.
}
@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 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, int[] ids);
public <T> void delete(Class<T> clazz, long[] ids);
/**
* 根据主键值删除对象, 必须是Entity Class
*

View File

@@ -149,7 +149,7 @@ final class EntityCache<T> {
public void insert(T value) {
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);
if (old != null) logger.log(Level.WARNING, "cache repeat insert data: " + value);
this.list.add(rs);