This commit is contained in:
@@ -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">
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user