assembly打包后启动provider分析
assembly打包的目录结构
bin
start.bat
…..
conf
dubbo.properties
lib
所有的jar包
assembly包的bin下的start.bat(windows下的启动脚本)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| @echo off & setlocal enabledelayedexpansion
set LIB_JARS="" cd ..\lib for %%i in (*) do set LIB_JARS=!LIB_JARS!;..\lib\%%i cd ..\bin
if ""%1"" == ""debug"" goto debug if ""%1"" == ""jmx"" goto jmx
java -Xms64m -Xmx1024m -XX:MaxPermSize=64M -classpath ..\conf;%LIB_JARS% com.alibaba.dubbo.container.Main goto end
:debug java -Xms64m -Xmx1024m -XX:MaxPermSize=64M -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n -classpath ..\conf;%LIB_JARS% com.alibaba.dubbo.container.Main goto end
:jmx java -Xms64m -Xmx1024m -XX:MaxPermSize=64M -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -classpath ..\conf;%LIB_JARS% com.alibaba.dubbo.container.Main
:end pause
|
java -Xms64m -Xmx1024m -XX:MaxPermSize=64M -classpath ..\conf;%LIB_JARS% com.alibaba.dubbo.container.Main
根据以上的理解,该命令是执行com.alibaba.dubbo.container.Main
但是该类需要依赖许多其他类,因此需要指定-classpath (..\conf是一个配置文件,将其加入到
classpath中,%LIB_JARS%是执行com.alibaba.dubbo.container.Main所依赖的所有jar包路径,
也将其加载到classpath中,这样,com.alibaba.dubbo.container.Main才可以正确执行)
注意:
加入echo %LIB_JARS% 测试打印结果
1
| "";..\lib\aopalliance-1.0.jar;..\lib\aspectjweaver-1.8.4.jar;..\lib\commons-logging-1.2.jar;..\lib\druid-1.0.9.jar;..\lib\dubbo-2.5.4.jar;..\lib\dubbo-mapper-0.0.1-SNAPSHOT.jar;..\lib\dubbo-pojo-0.0.1-SNAPSHOT.jar;..\lib\dubbo-user-interface-0.0.1-SNAPSHOT.jar;..\lib\dubbo-user-service-0.0.1-SNAPSHOT.jar;..\lib\hamcrest-core-1.3.jar;..\lib\javassist-3.20.0-GA.jar;..\lib\jline-0.9.94.jar;..\lib\junit-4.12.jar;..\lib\log4j-1.2.16.jar;..\lib\mybatis-3.2.8.jar;..\lib\mybatis-spring-1.2.2.jar;..\lib\mysql-connector-java-5.1.32.jar;..\lib\netty-3.2.5.Final.jar;..\lib\netty-3.7.0.Final.jar;..\lib\slf4j-api-1.6.1.jar;..\lib\slf4j-log4j12-1.6.4.jar;..\lib\spring-aop-4.1.3.RELEASE.jar;..\lib\spring-aspects-4.1.3.RELEASE.jar;..\lib\spring-beans-4.1.3.RELEASE.jar;..\lib\spring-context-4.1.3.RELEASE.jar;..\lib\spring-core-4.1.3.RELEASE.jar;..\lib\spring-expression-4.1.3.RELEASE.jar;..\lib\spring-jdbc-4.1.3.RELEASE.jar;..\lib\spring-tx-4.1.3.RELEASE.jar;..\lib\spring-web-4.1.3.RELEASE.jar;..\lib\zkclient-0.10.jar;..\lib\zookeeper-3.4.8.jar
|
是所有jar的路径,通过-classpath将其加入到类路径中,这样就可以jvm就可以加载到这些jar中的.class或者资源文件
linux环境下运行问题
问题1:启动provider
以下是start.sh部分代码,linux下的执行脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| JAVA_OPTS=" -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true " JAVA_DEBUG_OPTS="" if [ "$1" = "debug" ]; then JAVA_DEBUG_OPTS=" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n " fi JAVA_JMX_OPTS="" if [ "$1" = "jmx" ]; then JAVA_JMX_OPTS=" -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false " fi JAVA_MEM_OPTS="" BITS=`java -version 2>&1 | grep -i 64-bit` if [ -n "$BITS" ]; then JAVA_MEM_OPTS=" -server -Xmx2g -Xms2g -Xmn256m -XX:PermSize=128m -Xss256k -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 " else JAVA_MEM_OPTS=" -server -Xms1g -Xmx1g -XX:PermSize=128m -XX:SurvivorRatio=2 -XX:+UseParallelGC " fi
echo -e "Starting the $SERVER_NAME ...\c" nohup java $JAVA_OPTS $JAVA_MEM_OPTS $JAVA_DEBUG_OPTS $JAVA_JMX_OPTS -classpath $CONF_DIR:$LIB_JARS com.alibaba.dubbo.container.Main > $STDOUT_FILE 2>&1 &
|
注意:
java $JAVA_OPTS $JAVA_MEM_OPTS $JAVA_DEBUG_OPTS $JAVA_JMX_OPTS -classpath $CONF_DIR:$LIB_JARS com.alibaba.dubbo.container.Main > $STDOUT_FILE 2>&1 &
使用了JVM参数,如果配置不当,则会导致服务无法启动,直接jvm错误(产生hs_err_pid8647.log日志文件)
目前不会配置,因此直接删除JVM参数即可,java -classpath $CONF_DIR:$LIB_JARS com.alibaba.dubbo.container.Main > $STDOUT_FILE 2>&1 &
问题2:consumer调用provider
consumer调用provider总是产生Timeout,原本是以为服务运行时间过长导致的,于是在provider中
的META-INF/spring/application-dubbo.xml配置
1 2
| <!-- 设置超时时间 --> <dubbo:provider timeout="5000"></dubbo:provider>
|
在dubbo-admin中可以看到超时时间被设置为5s,但是还是出现Timeout,不是该问题
以下是报异常的部分代码
root cause:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| com.alibaba.dubbo.remoting.TimeoutException: Waiting server-side response timeout. start time: 2019-08-26 19:52:03.221, end time: 2019-08-26 19:52:08.222, client elapsed: 0 ms, server elapsed: 5001 ms, timeout: 5000 ms, request: Request [id=6, version=2.0.0, twoway=true, event=false, broken=false, data=RpcInvocation [methodName=selectUsersAll, parameterTypes=[], arguments=[], attachments={path=com.bjsxt.dubbo.service.FindUserDubboService, interface=com.bjsxt.dubbo.service.FindUserDubboService, version=0.0.0, timeout=5000}]], channel: /192.168.1.112:48407 -> /192.168.1.113:20880 com.alibaba.dubbo.remoting.exchange.support.DefaultFuture.get(DefaultFuture.java:136) com.alibaba.dubbo.remoting.exchange.support.DefaultFuture.get(DefaultFuture.java:113) com.alibaba.dubbo.rpc.protocol.dubbo.DubboInvoker.doInvoke(DubboInvoker.java:97) com.alibaba.dubbo.rpc.protocol.AbstractInvoker.invoke(AbstractInvoker.java:144) com.alibaba.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:75) com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:69) com.alibaba.dubbo.rpc.protocol.dubbo.filter.FutureFilter.invoke(FutureFilter.java:54) com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:69) com.alibaba.dubbo.rpc.filter.ConsumerContextFilter.invoke(ConsumerContextFilter.java:48) com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:69) com.alibaba.dubbo.rpc.listener.ListenerInvokerWrapper.invoke(ListenerInvokerWrapper.java:74) com.alibaba.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:53) com.alibaba.dubbo.rpc.cluster.support.FailoverClusterInvoker.doInvoke(FailoverClusterInvoker.java:77) com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker.invoke(AbstractClusterInvoker.java:229) com.alibaba.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker.invoke(MockClusterInvoker.java:72) com.alibaba.dubbo.rpc.proxy.InvokerInvocationHandler.invoke(InvokerInvocationHandler.java:52) com.alibaba.dubbo.common.bytecode.proxy1.selectUsersAll(proxy1.java) com.bjsxt.service.impl.UserServiceImpl.selectUserAll(UserServiceImpl.java:42) com.bjsxt.controller.UsersController.findAll(UsersController.java:31) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:483) org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777) org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:706) org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857) javax.servlet.http.HttpServlet.service(HttpServlet.java:621) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) javax.servlet.http.HttpServlet.service(HttpServlet.java:728) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
|
问题解决:
provider(192.168.1.113)中使用的是192.168.1.103的主机的mysql,而192.168.1.103的防火墙需要打开
然后重启provider即可.
注意:
consumer和provider两台主机需要开放dubbo协议连接的所需端口(连接形成一个channel: /192.168.1.112:52877 -> /192.168.1.113:20880)
1)provider:配置服务端口
linux中开放服务端口,例如20880(或者关闭防火墙,否则consumer启动失败)
iptables相关配置:
1 2 3 4 5 6
| 1)iptables -nL --line-number 查看规则,行号 2)iptables -D INPUT 6 删除行号为6的规则 # 因为最后一行是reject-with icmp-host-prohibited,拒绝所有,因此需要插入到最后一行前面 3)iptables -I INPUT 3 -p tcp --dport 8080 -j ACCEPT 添加规则插入到第3行, #注意不要使用service iptables restart,否则规则会到最后一行 4)iptables-save 保存即可
|
2)consumer:
请求连接并获得回应:channel: /192.168.1.112:37711 -> /192.168.1.113:20880
注意:37711端口没有开放为什么可以得到回应?
1 2 3 4 5
| IPtable第一条规则 1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 这个想要进入的封包是否为刚刚我发出去的回应?如果是刚刚我发出去的回应,那麼就可以予以接受放行. ESTABLISHED:已建立的链接状态. RELATED:该封包为本机发出的封包有关.
|
192.168.1.112:37711向192.168.1.113:20880请求服务,provider处理完毕,再通过192.168.1.113:20880将结果回应给192.168.1.112:37711。
由于是37711建立的连接,按照iptables的第一条规则所以允许接收,因此consumer的37711这个端口可以不建立iptables放行规则。
Dubbo注册IP混乱的问题
windows
关闭其他网卡服务,例如虚拟机的vmnet1,vmnet8
linux
a) 通过hostname命令得到机器名
b) 通过vim /etc/hosts设置机器名对应的外网IP
127.0.0.1 localhost localhost.localdomain
外网IP VM_31_182_centos
示例配置:
1 2 3
| 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.1.112 slave1
|
consumer启动问题以及远程部署
远程部署consumer
通过maven插件远程部署consumer(一个web项目)至tomcat,由于 zookeeper 注册中心没有开启,
因此consumer无法从zookeeper获取服务接口信息,初始化会失败,即项目启动失败。
注意:
远程部署需要配置tomcat用户,conf/tomcat-users.xml
1 2 3
| <role rolename="manager-gui"/> <role rolename="manager-script"/> <user username="tomcat" password="tomcat" roles="manager-gui,manager-script"/>
|
将consumer项目拷贝至tomcat的webapps下
注意:
在consumer的项目中,如果使用的某些路径是/,则要将其拷贝至ROOT中
将consumer拷贝至webapps目录下,启动tomcat,如果zookeeper注册中心没有启动,
或者zookeeper启动但是consumer无法获取需要的服务接口信息,都会导致consumer启动
失败.