#
一套S2SH的应用,现用单线程,连续发1000个请求,用的DBCP链接池,结果报数据库链接不够用:
ERROR [org.hibernate.util.JDBCExceptionReporter] - Cannot get a connection, pool error Timeout waiting for idle object
在JAVA加上LOG:
log.info("active: " + dataSource.getNumActive() + " (max: "
+ dataSource.getMaxActive() + ") " + "idle: " + dataSource.getNumIdle()
+ "(max: " + dataSource.getMaxIdle() + ")");
结果显示为:
active: 25 (max: 100) idle: 0(max: 30)
active的数量一直增加,但idle的数量一直为0。当程序向链接池要链接的时候,如果池没有,就会新建一个,active数就会加1,关闭链接后,链接会返回池,idle数加1。idle为0则表示池里没有链接。
这样说明链接一直在创建,没有关闭放回池里。但链接是由SPRING和HIBERNATE管理的,代码中没有关闭链接的语句。之后试了N多配置,都还没解决,如增加maxActive数等。最后,加上这一行,问题才终于解决:
<prop key="hibernate.connection.release_mode">after_transaction</prop>
这里默认值是auto,如果是用JTA事务才适用,如果是JDBC事务,就只能用after_transaction。
这样每次事务结束后,就会关闭链接返回链接池。
管理层级 |
序列层级 | 职衔 | 对应T序 | 薪资区间(技术) |
M5 | CXO | —— | —— |
M5 | VP | —— | —— |
M4-3 | 高级总监 | —— | —— |
M4-2 | 总监 | T5 | 40-50k |
M4-1 | 副总监 | T5 | 35-45k |
M3 | 高级经理 | T4-2 | 30-40k |
M2-2 | 经理 | T4-1 | 25-35k |
M2-1 | 副经理 | T3-2 | 20-30k |
M1 | 主管 | T3-1 | 15-25k |
技术层级 |
序列层级 | 职衔 | 对应M序 | 薪资区间(技术) |
T5-3 | 专家3 | 总监/副总监 | 35-50k |
T5-2 | 专家2 | 总监/副总监 | 35-50k |
T5-1 | 专家1 | 总监/副总监 | 35-50k |
T4-2 | 资深2 | 高级经理 | 30-40k |
T4-1 | 资深1 | 经理 | 25-35k |
T3-2 | 高级2 | 副经理 | 20-30k |
T3-1 | 高级1 | 主管 | 15-25k |
T2-2 | 中级2 | —— | 10-20K |
T2-1 | 中级1 | —— | 5-15K |
T1-2 | 初级2 | —— | 5-10K |
T1-1 | 初级1 | —— | 0-8k |
ANDROID APP 与 WEB APP有相似之处,都是需要在容器内运行,都可以对事件进行响应。
WEB APP的核心组件是SERVLET,这是对游览器事件进行响应的一个类,事件有GET/POST等事件,不同的URL对应不同的SERVLET。
如果要输出不同的内容,则输出不同的HTML即可。
WEB APP的配置文件是WEB.XML,当容器启动时,会从这读取有多少个SERVLET。当浏览器发过来不同的URL请求时,会从中选择相应的SERVLET执行。
ANDROID APP的核心组件是ACTIVITY,这是一个对系统事件进行响应的一个类,事件有启动事件,菜单点击事件等,点击不同的地方对应不同的ACTIVITY。
如果要输出不同的内容,则输出不同的VIEW即可。
ANDROID APP的配置文件是MAINFRE.XML,当应用被部署到系统时,系统会从这读取有多少个ACTIVITY。当不同的事件发生时,系统会会从中选择相应的ACTIVITY执行。
The architecture representation will basically adopt the 4 + 1 View Model as
recommended, to organize the architectural description from different perspectives, each
of which addresses a specific set of concerns:
• Requirement View – describes the software requirements, functional and
non-functional, illustrated by significant use cases and scenarios.
• Logical View – describes the object model of the design, the system
decomposition into layers and subsystems, and the dependencies between them.
• Process View – describes the concurrency and synchronization aspects of the
design.
• Implementation View – describes the software’s static organization in the
development environment.
• Deployment View – describes the mapping of the software onto hardware.
• Data View – describes the database design for the software.
It allows various stakeholders to find what they need in the software architecture. System
engineers can approach it from the logical view, process view and deployment view. DBA
can approach it from the data view. Project managers and software configuration
managers can approach it from the development view.
Demo:
- CUHK RFID - White Paper

- Middleware Quick Start Guide

- Tag Capturer Quick Start Guide

- Middleware System Design Document

- Tag Capturer System Design Document

- Middleware Test Cases

- Middleware Test Plan

- Middleware Source Code

|
数据导出:
1 将数据库TEST完全导出,用户名system 密码manager 导出到D:\daochu.dmp中
exp system/manager@TEST file=d:\daochu.dmp full=y
2 将数据库中system用户与sys用户的表导出
exp system/manager@TEST file=d:\daochu.dmp owner=(system,sys)
3 将数据库中的表table1 、table2导出
exp system/manager@TEST file=d:\daochu.dmp tables=(table1,table2)
4 将数据库中的表table1中的字段filed1以"00"打头的数据导出
exp system/manager@TEST file=d:\daochu.dmp tables=(table1)query=\" where filed1 like '00%'\"
上面是常用的导出,对于压缩我不太在意,用winzip把dmp文件可以很好的压缩。
不过在上面命令后面 加上 compress=y 就可以了
数据的导入
1 将D:\daochu.dmp 中的数据导入 TEST数据库中。
imp system/manager@TEST file=d:\daochu.dmp
上面可能有点问题,因为有的表已经存在,然后它就报错,对该表就不进行导入。
在后面加上 ignore=y 就可以了。
2 将d:\daochu.dmp中的表table1 导入
imp system/manager@TEST file=d:\daochu.dmp tables=(table1)
基本上上面的导入导出够用了。不少情况我是将表彻底删除,然后导入。
注意:
你要有足够的权限,权限不够它会提示你。
数据库时可以连上的。可以用tnsping TEST 来获得数据库TEST能否连上
附录一:
给用户增加导入数据权限的操作
第一,启动sql*puls
第二,以system/manager登陆
第三,create user 用户名 IDENTIFIED BY 密码 (如果已经创建过用户,这步可以省略)
第四,GRANT CREATE USER,DROP USER,ALTER USER ,CREATE ANY VIEW ,
DROP ANY VIEW,EXP_FULL_DATABASE,IMP_FULL_DATABASE,
DBA,CONNECT,RESOURCE,CREATE SESSION TO 用户名字
第五, 运行-cmd-进入dmp文件所在的目录,
imp userid=system/manager full=y file=*.dmp
或者 imp userid=system/manager full=y file=filename.dmp
安装oracle9I
Szportdb\szportdb\szportdb
用sysdba 登录建立用户:szportdb 表空间可以自己设定,也可以Users
倒入数据库。
Imp szportdb/szportdb@szportdb full=y C:\szportdb.dmp ignore=
1、前言
Apache MINA是Apache组织的一个优秀的项目。MINA是Multipurpose Infrastructure for NetworkApplications的缩写。它是一个网络应用程序框架,用来帮助用户非常方便地开发高性能和高可靠性的网络应用程序。在本文中介绍了 如何通过Apache Mina2.0来实现TCP协议长连接和短连接应用。
2、系统介绍
2.1系统框架
整个系统由两个服务端程序和两个客户端程序组成。分别实现TCP长连接和短连接通信。
系统业务逻辑是一个客户端与服务端建立长连接,一个客户端与服务端建立短连接。数据从短连接客户端经过服务端发送到长连接客户端,并从长连接客户端接收响应数据。当收到响应数据后断开连接。
系统架构图如下:
2.2处理流程
系统处理流程如下:
1) 启动服务端程序,监听8001和8002端口。
2) 长连接客户端向服务端8002端口建立连接,服务端将连接对象保存到共享内存中。由于采用长连接方式,连接对象是唯一的。
3) 短连接客户端向服务端8001端口建立连接。建立连接后创建一个连接对象。
4) 短连接客户端连接成功后发送数据。服务端接收到数据后从共享内存中得到长连接方式的连接对象,使用此对象向长连接客户端发送数据。发送前将短连接对象设为长连接对象的属性值。
5) 长连接客户端接收到数据后返回响应数据。服务端从长连接对象的属性中取得短连接对象,通过此对象将响应数据发送给短连接客户端。
6) 短连接客户端收到响应数据后,关闭连接。
3、服务端程序
3.1长连接服务端
服务启动
public class MinaLongConnServer {
private static final int PORT = 8002;
public void start()throws IOException{
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
acceptor.getFilterChain().addLast("codec", newProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
acceptor.setHandler(new MinaLongConnServerHandler());
acceptor.getSessionConfig().setReadBufferSize(2048);
acceptor.bind(new InetSocketAddress(PORT));
System.out.println("Listeningon port " + PORT);
}
}
//消息处理
public class MinaLongConnServerHandler extends IoHandlerAdapter {
private final Logger logger = (Logger) LoggerFactory.getLogger(getClass());
@Override
public void sessionOpened(IoSession session) {
InetSocketAddress remoteAddress = (InetSocketAddress)session.getRemoteAddress();
String clientIp = remoteAddress.getAddress().getHostAddress();
logger.info("LongConnect Server opened Session ID ="+String.valueOf(session.getId()));
logger.info("接收来自客户端 :" + clientIp + "的连接.");
Initialization init = Initialization.getInstance();
HashMap<String, IoSession> clientMap =init.getClientMap();
clientMap.put(clientIp, session);
}
@Override
public void messageReceived(IoSession session, Object message) {
logger.info("Messagereceived in the long connect server..");
String expression = message.toString();
logger.info("Message is:" + expression);
IoSession shortConnSession =(IoSession) session.getAttribute("shortConnSession");
logger.info("ShortConnect Server Session ID ="+String.valueOf(shortConnSession.getId()));
shortConnSession.write(expression);
}
@Override
public void sessionIdle(IoSession session, IdleStatus status) {
logger.info("Disconnectingthe idle.");
// disconnect an idle client
session.close(true);
}
@Override
public void exceptionCaught(IoSession session, Throwable cause) {
// close the connection onexceptional situation
logger.warn(cause.getMessage(), cause);
session.close(true);
}
}
3.2短连接服务端
服务启动
public class MinaShortConnServer {
private static final int PORT = 8001;
public void start()throws IOException{
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
acceptor.getFilterChain().addLast("codec", newProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
acceptor.setHandler(new MinaShortConnServerHandler());
acceptor.getSessionConfig().setReadBufferSize(2048);
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 3);
acceptor.bind(new InetSocketAddress(PORT));
System.out.println("Listeningon port " + PORT);
}
}
消息处理
public class MinaShortConnServerHandler
extends IoHandlerAdapter {
private final Logger logger = (Logger) LoggerFactory.getLogger(getClass());
@Override
public void sessionOpened(IoSession session) {
InetSocketAddress remoteAddress = (InetSocketAddress)session.getRemoteAddress();
logger.info(remoteAddress.getAddress().getHostAddress());
logger.info(String.valueOf(session.getId()));
}
@Override
public void messageReceived(IoSession session, Object message) {
logger.info("Messagereceived in the short connect server

");
String expression = message.toString();
Initialization init = Initialization.getInstance();
HashMap<String, IoSession> clientMap =init.getClientMap();
if (clientMap ==
null || clientMap.size() == 0) {
session.write("error");
}
else {
IoSession longConnSession =
null;
Iterator<String> iterator =clientMap.keySet().iterator();
String key = "";
while (iterator.hasNext()) {
key = iterator.next();
longConnSession = clientMap.get(key);
}
logger.info("ShortConnect Server Session ID :"+String.valueOf(session.getId()));
logger.info("LongConnect Server Session ID :"+String.valueOf(longConnSession.getId()));
longConnSession.setAttribute("shortConnSession",session);
longConnSession.write(expression);
}
}
@Override
public void sessionIdle(IoSession session, IdleStatus status) {
logger.info("Disconnectingthe idle.");
// disconnect an idle client
session.close(
true);
}
@Override
public void exceptionCaught(IoSession session, Throwable cause) {
// close the connection onexceptional situation
logger.warn(cause.getMessage(), cause);
session.close(
true);
}
}
4、客户端程序
4.1长连接客户端
使用java.net.Socket来实现向服务端建立连接。Socket建立后一直保持连接,从服务端接收到数据包后直接将原文返回。
public class TcpKeepAliveClient {
private String ip;
private int port;
private static Socket socket = null;
private static int timeout = 50 * 1000;
public TcpKeepAliveClient(String ip, int port) {
this.ip = ip;
this.port = port;
}
public void receiveAndSend() throws IOException {
InputStream input = null;
OutputStream output = null;
try {
if (socket == null || socket.isClosed() || !socket.isConnected()) {
socket = new Socket();
InetSocketAddress addr = new InetSocketAddress(ip, port);
socket.connect(addr, timeout);
socket.setSoTimeout(timeout);
System.out.println("TcpKeepAliveClientnew ");
}
input = socket.getInputStream();
output = socket.getOutputStream();
// read body
byte[] receiveBytes = {};// 收到的包字节数组
while (true) {
if (input.available() > 0) {
receiveBytes = new byte[input.available()];
input.read(receiveBytes);
// send
System.out.println("TcpKeepAliveClientsend date :" + new String(receiveBytes));
output.write(receiveBytes, 0, receiveBytes.length);
output.flush();
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("TcpClientnew socket error");
}
}
public static void main(String[] args) throws Exception {
TcpKeepAliveClient client = new TcpKeepAliveClient("127.0.0.1", 8002);
client.receiveAndSend();
}
}
4.2短连接客户端
服务启动
public class MinaShortClient {
private static final int PORT = 8001;
public static void main(String[] args) throws IOException,InterruptedException {
IoConnector connector = new NioSocketConnector();
connector.getSessionConfig().setReadBufferSize(2048);
connector.getFilterChain().addLast("logger", new LoggingFilter());
connector.getFilterChain().addLast("codec", newProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
connector.setHandler(new MinaShortClientHandler());
for (int i = 1; i <= 10; i++) {
ConnectFuture future = connector.connect(new InetSocketAddress("127.0.0.1", PORT));
future.awaitUninterruptibly();
IoSession session =future.getSession();
session.write(i);
session.getCloseFuture().awaitUninterruptibly();
System.out.println("result=" + session.getAttribute("result"));
}
connector.dispose();
}
}
消息处理
public class MinaShortClientHandler extends IoHandlerAdapter{
private final Logger logger = (Logger) LoggerFactory.getLogger(getClass());
public MinaShortClientHandler() {
}
@Override
public void sessionOpened(IoSession session) {
}
@Override
public void messageReceived(IoSession session, Object message) {
logger.info("Messagereceived in the client..");
logger.info("Message is:" + message.toString());
session.setAttribute("result", message.toString());
session.close(true);
}
@Override
public void exceptionCaught(IoSession session, Throwable cause) {
session.close(true);
}
}
5、总结
通过本文中的例子,Apache Mina在服务端可实现TCP协议长连接和短连接。在客户端只实现了短连接模式,长连接模式也是可以实现的(在本文中还是采用传统的java Socket方式)。两个服务端之间通过共享内存的方式来传递连接对象也许有更好的实现方式。