如何从docker化的Tomee服务器上运行的应用程序成功连接到Dockerized DB2 DB服务器 – 两个容器都使用jdk10?
到目前为止我试图做的……
将db2jcc4.jar删入“/usr/local/tomee / lib”文件夹…
…从…获取:
https://www-01.ibm.com/support/docview.wss?uid=swg21385217
Fwiw,tomcat服务器的初始启动抱怨它无法找到pdq.jar …:
05-Sep-2018 16:48:04.901 INFO [localhost-startStop-1] org.apache.openejb.assembler.classic.Assembler.createApplication Deployed Application(path=C:\tools\apache-tomee-plume-7.0.5\webapps\docs)
05-Sep-2018 16:48:04.956 WARNING [localhost-startStop-1] org.apache.tomcat.util.scan.StandardJarScanner.processURLs Failed to scan [file:/C:/tools/apache-tomee-plume-7.0.5/lib/pdq.jar] from classloader hierarchy
java.io.IOException: java.lang.reflect.InvocationTargetException
at org.apache.tomcat.util.compat.Jre9Compat.jarFileNewInstance(Jre9Compat.java:212)
at org.apache.tomcat.util.scan.JarFileUrlJar.
…所以我从jar的manifest类路径中删除了pdq.jar,之后启动了tomee / tomcat服务器.
我部署了一个简单的REST应用程序 – 包含一个GET方法 – 利用一个简单的jdbc调用从IBM“SAMPLE”数据库(与db2express-c捆绑在一起)中提取数据
该应用程序看起来像这样……
package aaa.bbb.ccc.war;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.sqlException;
import java.sql.Statement;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.sql.DataSource;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import aaa.bbb.ccc.generated.EmployeeList;
import aaa.bbb.ccc.generated.EmployeeType;
import aaa.bbb.ccc.generated.ObjectFactory;
@Stateless
@Path("/employeeList")
public class MyRestSvc {
@Context
UriInfo uriInfo;
public MyRestSvc() {
}
@Resource(name = "jdbc/sample",type = javax.sql.DataSource.class)
private DataSource sampleDb;
@GET
@Path("{empno}")
@Produces({ MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML })
public EmployeeList get(@Context javax.servlet.http.HttpServletRequest request,@PathParam("empno") String empno) {
String empNo = null;
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
try {
con = sampleDb.getConnection();
con.setAutoCommit(false);
// Create the Statement
stmt = con.createStatement();
System.out.println("**** Created JDBC Statement object");
// Execute a query and generate a ResultSet instance
rs = stmt.executeQuery("SELECT EMPNO FROM EMPLOYEE");
System.out.println("**** Created JDBC ResultSet object");
// Print all of the employee numbers to standard output device
while (rs.next()) {
empNo = rs.getString(1);
System.out.println("Employee number = " + empNo);
}
System.out.println("**** Fetched all rows from JDBC ResultSet");
// Close the ResultSet
rs.close();
System.out.println("**** Closed JDBC ResultSet");
// Close the Statement
stmt.close();
System.out.println("**** Closed JDBC Statement");
// Connection must be on a unit-of-work boundary to allow close
con.commit();
System.out.println("**** Transaction committed");
// Close the connection
con.close();
} catch (sqlException e) {
e.printStackTrace();
} finally {
if (con != null) {
System.out.println("Connected successfully.");
try {
con.close();
} catch (sqlException e) {
e.printStackTrace();
}
}
}
return new EmployeeList();
}
}
我运行了一个测试curl命令来执行GET操作……
即,
curl -k -v -L -H "Content-Type: application/xml" -X GET http://localhost:8888/MyRestSvc/employeeList/000190
并收到此例外……
“异常java.net.ConnectException:在端口50,000上打开到服务器localhost / 127.0.0.1的套接字时出错:消息:Connection refused(Connection refused).ERRORCODE = -4499,sqlSTATE = 08001
“
即,
-
-
-
10-Sep-2018 21:04:15.767 INFO [main] org.apache.openejb.assembler.classic.Assembler.createRecipe Creating Resource(id=jdbc/sample)
10-Sep-2018 21:04:16.173 SEVERE [main] org.apache.tomcat.jdbc.pool.ConnectionPool.init Unable to create initial connections of pool.
com.ibm.db2.jcc.am.DisconnectNonTransientConnectionException: [jcc][t4][2043][11550][4.21.29] Exception java.net.ConnectException: Error opening socket to server localhost/127.0.0.1 on port 50,000 with message: Connection refused (Connection refused). ERRORCODE=-4499,sqlSTATE=08001
at com.ibm.db2.jcc.am.kd.a(kd.java:338)
at com.ibm.db2.jcc.am.kd.a(kd.java:435)
at com.ibm.db2.jcc.t4.ac.a(ac.java:440)
at com.ibm.db2.jcc.t4.ac.opening socket to server localhost/127.0.0.1 on port 50,sqlSTATE=08001
at com.ibm.db2.jcc.am.kd.a(kd.java:338)
at com.ibm.db2.jcc.am.kd.a(kd.java:435)
at com.ibm.db2.jcc.t4.ac.a(ac.java:440)
at com.ibm.db2.jcc.t4.ac.
研究,发现这个链接……:
http://www-01.ibm.com/support/docview.wss?uid=swg21287078
…但是,“解决方案”似乎假设tomee服务器和db2服务器都在同一台机器上(?)…
另外,fwiw ……
这是tomee / tomcat server.xml …
这是tomee / tomcat tomee.xml …
sql.DataSource">
driverClassName = com.ibm.db2.jcc.DB2Driver
jdbcDriverType = 4
url = jdbc:db2://localhost:50000/SAMPLE
username = DB2INST1
password = mydb2-pwd
用于生成apache-tomee-plume-7.0.5 docker容器的Dockerfile …
FROM openjdk:10-jre
ENV PATH /usr/local/tomee/bin:$PATH
RUN mkdir -p /usr/local/tomee
WORKDIR /usr/local/tomee
# curl -fsSL 'https://www.apache.org/dist/tomee/KEYS' | awk -F ' = ' '$1 ~ /^ +Key fingerprint$/ { gsub(" ","",$2); print $2 }' | sort -u
ENV GPG_KEYS \
223D3A74B068ECA354DC385CE126833F9CF64915 \
678F2D98F1FD9643811639FB622B8F2D043F71D8 \
7A2744A8A9AAF063C23EB7868EBE7DBE8D050EEF \
82D8419BA697F0E7FB85916EE91287822FDB81B1 \
9056B710F1E332780DE7AF34CBAEBE39A46C4CA1 \
A57DAF81C1B69921F4BA8723A8DE0A4DB863A7C1 \
B7574789F5018690043E6DD9C212662E12F3E1DD \
B8B301E6105DF628076BD92C5483E55897ABD9B9 \
BDD0BBEB753192957EFC5F896A62FC8EF17D8FEF \
C23A3F6F595EBD0F960270CC997C8F1A5BE6E4C1 \
D11DF12CC2CA4894BDE638B967C1227A2678363C \
DBCCD103B8B24F86FFAAB025C8BB472CD297D428 \
F067B8140F5DD80E1D3B5D92318242FE9A0B1183 \
FAA603D58B1BA4EDF65896D0ED340E0E6D545F97
RUN set -xe \
&& for key in $GPG_KEYS; do \
gpg --keyserver pgp.mit.edu --keyserver-options http-proxy=proxy.apps.dhs.gov:80 --recv-keys "$key" || \
gpg --keyserver keyserver.pgp.com --keyserver-options http-proxy=proxy.apps.dhs.gov:80 --recv-keys "$key" || \
gpg --keyserver ha.pool.sks-keyservers.net --keyserver-options http-proxy=proxy.apps.dhs.gov:80 --recv-keys "$key" ; \
done
RUN set -x \
&& curl -fSL https://repo.maven.apache.org/maven2/org/apache/tomee/apache-tomee/7.0.5/apache-tomee-7.0.5-plume.tar.gz.asc --proxy proxy.apps.dhs.gov:80 -o tomee.tar.gz.asc \
&& curl -fSL https://repo.maven.apache.org/maven2/org/apache/tomee/apache-tomee/7.0.5/apache-tomee-7.0.5-plume.tar.gz --proxy proxy.apps.dhs.gov:80 -o tomee.tar.gz \
&& gpg --batch --verify tomee.tar.gz.asc tomee.tar.gz \
&& tar -zxf tomee.tar.gz \
&& mv apache-tomee-plume-7.0.5/* /usr/local/tomee \
&& rm -Rf apache-tomee-plume-7.0.5 \
&& rm bin/*.bat \
&& rm tomee.tar.gz*
EXPOSE 8084
CMD ["catalina.sh","run"]
Dockerized DB2来自:
https://hub.docker.com/r/ibmcom/db2express-c/
Tomee创业公司:
root@5f9812df3398:/usr/local/tomee/bin# sh startup.sh
./catalina.sh: 165: ./catalina.sh: /docker-java-home=/docker-java-home: not found
Using CATALINA_BASE: /usr/local/tomee
Using CATALINA_HOME: /usr/local/tomee
Using CATALINA_TMPDIR: /usr/local/tomee/temp
Using JRE_HOME: /docker-java-home
Using CLASSPATH: /usr/local/tomee/bin/bootstrap.jar:/usr/local/tomee/bin/tomcat-juli.jar
Tomcat started.
环境:
openjdk 10(在tomee / db2 docker容器中运行)
tomee-plume-7.0.5(dockerized)
db2 11.x(dockerized)
> jdbc:db2://< host-machine-static-ip> ;:50000 / SAMPLE
> jdbc:db2://< docker-container-ip> ;:50000 / SAMPLE
> jdbc:db2://< docker-container-alias>:50000 / SAMPLE
让我简要解释一下.
我的假设:
> Tomcat服务器和数据库服务器作为不同的容器运行.
>两者都连接到不同的docker网络.
>您没有在数据库服务器中转发端口.
>您尚未为容器定义docker-compose文件.
>您正在使用docker run运行容器.
如果我的所有假设都正确,那么docker网络配置就会出现问题.
基本上,您可以通过不同的方式从一个容器连接到另一个容器.
>通过为每个容器定义别名并将其连接到同一网络(推荐).
>通过端口从主机转发到docker容器并使用主机的静态ip连接到该端口.
>通过在主机网络中运行容器并使用主机的静态IP连接到所需的端口.
>通过为docker容器定义静态ip并使用该ip从其他容器连接.
简要推荐的方式
您必须为容器定义别名,为此您可以使用服务名称,也可以声明其他别名.然后两者都应连接到同一网络,然后只有docker服务发现才能工作.完成所有操作后,您可以使用其他计算机的别名从一个容器连接到另一个容器.
参考文献:
> Work with network commands
> Use bridge networks
> Docker-compose alias
> Docker run reference