• [问题求助] 接收平台发来的数据后无法在tomcat的日志中打印接收的数据
    对平台发送来的数据,tomcat可以接收,但是在catalina.out中没有打印出数据。用eclipse将同样的程序运行在server上时,可以在控制台上查看到打印的数据。为什么catalina.out没有打印出平台发送来的数据呢?用的是自己电脑win7,tomcat,restful接口,jersey框架
  • [技术干货] Tomcat重复加载war包问题
    Tomcat重复加载war包问题问题现象有同事开发了一个demo服务,服务包含前端页面和ServiceComb开发的REST后端服务两部分。打成war包部署在Tomcat中,发现这个服务会在服务中心注册两个地址相同的实例。观察日志,发现Spring Context加载了两遍,并且Tomcat的webapps目录下存在一个与war包同名的目录和一个ROOT目录,两个目录中的内容是相同的。问题原因Tomcat在启动时会将webapps目录下的war包解压到一个同名目录下,将其作为一个context加载。而在Tomcat的conf/server.xml文件中,又额外定义了一个Context:<Context path="/" reloadable="true" docBase="${war包的名字}"/>于是该war包会作为root context 又被加载一次。解决方案删掉conf/server.xml文件中定义的context,把拷贝到webapps目录下的war包改名为ROOT.war。Tomcat启动时会自动将war包解压作为root context加载。
  • [技术干货] tomcat+restful 接收https推送消息【转】
    (转自https://developer.huawei.com/ict/forum/forum.php?mod=viewthread&tid=47157  )有小伙伴问我怎么接收https推送我这边写了个简单的restful接口的webapp,部署到tomcat服务器上,大家可以测试一下1.首先先按下面的帖子配置好tomcat服务器https://bbs.huaweicloud.com/forum/thread-13220-1-1.html 2.将附件中的RESTfulWS.rar解压后放入tomcat的webapps目录下3.将服务器映射到公网上(公网ip及port会在下面的callbackurl中用到)4.运行脚本./startup.sh 启动tomcat服务器5.进入log目录输入tail -f catalina.out可以看到服务器日志6.用postman 调用post接口(也就是callbackurl)https://ip:port/RESTfulWS/rest/UserInfoService/subscriber1PS:这里postman证书配置按下面帖子操作:https://bbs.huaweicloud.com/forum/thread-13234-1-1.html  返回200 ok即为成功7.此时会在tomcat的log界面看到调用接口推过来的数据8.调用北向的app订阅数据接口(callbackurl:https://ip:port/RESTfulWS/rest/UserInfoService/subscriber1)9.触发推送操作即可。注意:1.可以自己安装openssl验证一下之前配置的证书是否匹配A.单项认证服务器配置:验证证书:标黄的地方改成自己服务器的IP端口和根证书文件若证书没问题执行之后会返回B.双向认证服务器配置:验证证书:标黄的部分分别替换成:接受推送服务器的IP端口、华为outgoing.CertwithKey.pkcs12转换后的pem证书、接受推送服务器的根证书。若证书没问题执行之后会返回2.上传证书后,可以找华为支持人员查看后台证书是否已经更新成功。RESTfulWS.rar
  • [技术干货] 使用Tomcat作为服务器,并采用CSE客户端调用,低概率出现请求失败
    问题现象和场景:  服务端使用Tomcat作为服务器, 客户端使用CSE调用。在大规模并发的场景下,低概率出现请求失败问题原因:Tomcat默认会在一定周期内(IDLE),达到一定请求数后关闭连接(active requests)关闭HTTP连接,导致请求失败。 解决方案:对于使用Tomcat + CSE SDK场景,使用Tomcat做HTTP协议接入的业务,临时规避方案如下(Tomcat的server.xml文件):1、  maxKeepAliveRequests修改为-12、  keepAliveTimeout修改为10分钟修改策略是:对于内部的RPC调用,尽量不要频繁的重建HTTP连接,HTTP空闲连接的回收时间配置长一些,5分钟或者10分钟,或者由CSE 消费端来控制,Tomcat服务端不用控制。最终解决方案:CSE给Vert.X社区提问题单,在下一个CSE版本中修复连接池的BUG,即:如果消息发送时发现连接不可用,要立即失败,并按照业务的重试策略自动重试,对业务的效果就是业务不感知底层HTTP连接的关闭和自动重试,保障业务的成功率。
  • [技术干货] 在本地配置https服务器详细流程【转】
    (转自https://developer.huawei.com/ict/forum/thread-25457.html)一:为服务器生成证书1. 找到jdk安装目录,运行控制台,切换到该目录:2. 使用keytool为tomcat生成证书:tomcat.keystore;keytool -genkey -v -alias tomcat -keyalg RSA -keystore tomcat.keystore -validity 36500二:为客户端生成证书1. 生成客户端证书:client.p12keytool -genkey -v -alias client -keyalg RSA -storetype PKCS12 -keystore client.p12 -validity 36500三:让服务器信任客户端证书1. 将client.p12转换成client.cer;keytool -export -alias client -keystore client.p12 -storetype PKCS12 -rfc -file client.cer2. 将client.cer导入到tomcat的信任证书链中keytool -import -alias client-v -file client.cer -keystore tomcat.keystore四:让客户端信任服务器证书1. 把tomcat证书导出为tomcat.cer文件(导出根证书)keytool -export -v -alias tomcat -file tomcat.cer -keystore tomcat.keystore2. 把tomcat.cer文件转换成tomcat.pem文件,并上传到IoT平台的应用(需要安装openssl)openssl x509 -inform der -in tomcat.cer -out tomcat.pem五:将华为提供的证书导入tomcat的信任证书链中1. 先将化为提供的outgoing.CertwithKey.pkcs12转换成outgoing.CertwithKey.pem证书  openssl pkcs12 -in outgoing.CertwithKey.pkcs12 -out outgoing.CertwithKey.pem      EnterImport Password为:IoM@1234,下面两个输入密码的地方可自行设置  再把outgoing.CertwithKey.pem导入tomcat的信任证书链  keytool -import -v -file outgoing.CertwithKey.pem -alias huawei_out -keystore tomcat.keystore2.先将ca.jks转换成ca.p12证书  keytool -importkeystore -srckeystore ca.jks -destkeystore ca.p12 -srcstoretype jks -deststoretype pkcs12     上面的两个输入密码的地方可自行设置, 源密钥库口令为:Huawei@123  再把ca.p12转换成ca.pem证书  openssl pkcs12 -in ca.p12 -out ca.pem      密码为上面自己设置的目标密钥库口令 最后把ca.pem导入tomcat的信任证书链  keytool -import -v -file ca.pem -alias huawei_ca -keystore tomcat.keystore    密码为生成服务器证书时设置的密码。六:配置Tomcat服务器属性说明:clientAuth:设置是否双向验证,默认为false,设置为true代表双向验证keystoreFile:服务器证书文件路径keystorePass:服务器证书密码truststoreFile:用来验证客户端证书的根证书,此例中就是服务器证书truststorePass:根证书密码七:测试1. 启动tomcat服务器找到tomcat安装目录,运行控制台,切换到该目录的bin文件夹下执行shutdown.bat和startup.bat命令开启tomcat服务器。2.在浏览器输入https://localhost:8443没有安装证书的时候页面显示如下:3.将outgoing.CertwithKey.pkcs12证书导入到个人4.将tomcat.cer证书导入到受信任的根证书颁发机构5.重启浏览器再次输入https://localhost:8443显示如下则证书配置成功
  • 需要一个tomcat7.0或者以后版本的镜像
    华为内网不支持从其他地方下载镜像文件,但是华为云首页上下载不到tomcat,急需,多谢!
  • [技术干货] 在本地配置https服务器详细流程
    一:为服务器生成证书1. 找到jdk安装目录,运行控制台,切换到该目录:2. 使用keytool为tomcat生成证书:tomcat.keystore;keytool -genkey -v -alias tomcat -keyalg RSA -keystore tomcat.keystore -validity 36500二:为客户端生成证书1. 生成客户端证书:client.p12keytool -genkey -v -alias client -keyalg RSA -storetype PKCS12 -keystore client.p12 -validity 36500三:让服务器信任客户端证书1. 将client.p12转换成client.cer;keytool -export -alias client -keystore client.p12 -storetype PKCS12 -rfc -file client.cer2. 将client.cer导入到tomcat的信任证书链中keytool -import -alias client-v -file client.cer -keystore tomcat.keystore四:让客户端信任服务器证书1. 把tomcat证书导出为tomcat.cer文件(导出根证书)keytool -export -v -alias tomcat -file tomcat.cer -keystore tomcat.keystore2. 把tomcat.cer文件转换成tomcat.pem文件,并上传到IoT平台的应用(需要安装openssl)openssl x509 -inform der -in tomcat.cer -out tomcat.pem五:将华为提供的证书导入tomcat的信任证书链中1. 先将化为提供的outgoing.CertwithKey.pkcs12转换成outgoing.CertwithKey.pem证书  openssl pkcs12 -in outgoing.CertwithKey.pkcs12 -out outgoing.CertwithKey.pem      EnterImport Password为:IoM@1234,下面两个输入密码的地方可自行设置  再把outgoing.CertwithKey.pem导入tomcat的信任证书链  keytool -import -v -file outgoing.CertwithKey.pem -alias huawei_out -keystore tomcat.keystore2.先将ca.jks转换成ca.p12证书  keytool -importkeystore -srckeystore ca.jks -destkeystore ca.p12 -srcstoretype jks -deststoretype pkcs12     上面的两个输入密码的地方可自行设置, 源密钥库口令为:Huawei@123  再把ca.p12转换成ca.pem证书  openssl pkcs12 -in ca.p12 -out ca.pem      密码为上面自己设置的目标密钥库口令 最后把ca.pem导入tomcat的信任证书链  keytool -import -v -file ca.pem -alias huawei_ca -keystore tomcat.keystore    密码为生成服务器证书时设置的密码。六:配置Tomcat服务器属性说明:clientAuth:设置是否双向验证,默认为false,设置为true代表双向验证keystoreFile:服务器证书文件路径keystorePass:服务器证书密码truststoreFile:用来验证客户端证书的根证书,此例中就是服务器证书truststorePass:根证书密码七:测试1. 启动tomcat服务器找到tomcat安装目录,运行控制台,切换到该目录的bin文件夹下执行shutdown.bat和startup.bat命令开启tomcat服务器。2.在浏览器输入https://localhost:8443没有安装证书的时候页面显示如下:3.将outgoing.CertwithKey.pkcs12证书导入到个人4.将tomcat.cer证书导入到受信任的根证书颁发机构5.重启浏览器再次输入https://localhost:8443显示如下则证书配置成功
  • [技术干货] Tomcat场景使用CSE,升级版本时服务调用失败问题定位案例
    1、升级背景CSE新版本(2.3.17)对微服务的故障隔离策略等进行了修改,为了验证微服务可靠性和服务治理相关的参数,将异步原型验证的微服务版本(java-chassis SDK)从2.3.8升级到了2.3.35之后,业务调用失败,日志里面频繁打印:Load balancer does not have available server for client: default,但是通过服务中心查询,以及日志中查看find instance关键字,都有一个实例。 业务采用Tomcat + SpringMVC + CSE SDK的方式开发,消息接入使用SpringMVC原生的DispatcherServlet, 然后通过CSE SDK调用后端的微服务。2、故障定位对报错日志分析,发现跟Transport相关,日志如下: not deployed transport rest, ignore rest: rest://localhost:9090     这种情况通常意味着系统REST transport没加载。但是检查了相关依赖,REST模块和tomcat的Servlet都是正确依赖的。 对部署的业务war包进行分析,发现包含多个不同版本的transport,而且版本跨度较大:    定位发现原来在版本升级时只改了CSE的版本号,打包时没有clean,导致老版本的CSE类库也被打进了安装包:增加clean参数重新打包,业务启动成功。3、总结1. 业务升级的时候,尽可能使用mvn clean install来构建新本版本。 多个jar包并存的情况,会产生很多莫名其妙的问题,可能浪费大量的定位时间。2. Tomcat集成新版本做了大量优化,并且增加了不同场景下的集成方式。CSE在Tomcat场景下的各种集成原理参考:https://docs.servicecomb.io/java-chassis/zh_CN/build-provider/protocol/rest-over-servlet.html
  • [技术干货] Tomcat场景下服务加载两次
    从日志看,tomcat启动后,CSE被加载了两次。 这种情况通常是因为用户将war应用部署到Tomcat的webapps/user-2.3.0.war,并且在server.xml中配置了上下文:        <Context path="/user" reloadable="true" docBase="user-2.3.0.war">        </Context>这个本身是tomcat的问题,这种情况下,相当于用户部署了/user-2.3.0和/user两个war包。 将user-2.3.0.war改为user.war问题就不存在了。 https://stackoverflow.com/questions/14488509/maven-how-to-rename-the-war-file-for-the-project
  • [行业前沿] 使用tomcat部署应用,注册的地址包含两个实例
    server.xml配置: 启动后注册了两个实例: rest://host:port/?urlPrefiex=/rest rest://host:port/?urlPrefiex=/pojo/rest
  • [行业前沿] 【ServiceComb最全 FAQ】 42个常见问题 大集锦2
    Q: swagger body参数类型定义错误,导致服务中心注册的内容没有类型信息现象描述:定义如下接口,将参数放到body传递 /testInherate: post: operationId: "testInherate" parameters: - in: "body" name: "xxxxx" required: false type: string responses: 200: description: "response of 200" schema: $ref: "#/definitions/ReponseImpl" Copy采用上面方式定义接口。在服务注册以后,从服务中心查询下来的接口type: string 丢失,变成了: /testInherate: post: operationId: "testInherate" parameters: - in: "body" name: "xxxxx" required: false responses: 200: description: "response of 200" schema: $ref: "#/definitions/ReponseImpl" Copy如果客户端没有放置swagger,还会报告如下异常: Caused by: java.lang.ClassFormatError: Method "testInherate" in class ? has illegal signature "CopyA:定义body参数的类型的时候,需要使用schema,不能直接使用type。 /testInherate: post: operationId: "testInherate" parameters: - in: "body" name: "request" required: false schema: type: string responses: 200: description: "response of 200" schema: $ref: "#/definitions/ReponseImpl" CopyQ: ServiceComb微服务框架服务调用是否使用长连接?A: http使用的是长连接(有超时时间),highway方式使用的是长连接(一直保持)。Q: 服务断连服务中心注册信息是否自动删除A: 服务中心心跳检测到服务实例不可用,只会移除服务实例信息,服务的静态数据不会移除。Q: 如果使用tomcat方式集成ServiceComb微服务框架,如何实现服务注册A: 如果使用cse sdk servlet方式(使用transport-rest-servlet依赖)制作为war包部署到tomcat,需要保证,服务描述文件(microservice.yaml)中rest端口配置和外置容器一致才能实现该服务的正确注册。否则无法感知tomcat开放端口。Q: 如果使用tomcat方式集成CSE微服务框架,服务注册的时候如何将war包部署的上下文注册到服务中心A: 发布服务接口的时候需要将war包部署的上下文(context)放在baseurl最前面,这样才能保证注册到服务中心的路径是完整的路径(包含了上下文)。实例: @path(/{context}/xxx) class ServiceA CopyQ: ServiceComb微服务框架如何实现数据多个微服务间透传A: 透传数据塞入: CseHttpEntity<xxxx.class> httpEntity = new CseHttpEntity<>(xxx); //透传内容 httpEntity.addContext("contextKey","contextValue"); ResponseEntity<String> responseEntity = RestTemplateBuilder.create().exchange("cse://springmvc/springmvchello/sayhello",HttpMethod.POST,httpEntity,String.class); Copy透传数据获取: @Override @RequestMapping(path="/sayhello",method = RequestMethod.POST) public String sayHello(@RequestBody Person person,InvocationContext context){ //透传数据获取 context.getContext(); return "Hello person " + person.getName(); } CopyQ: ServiceComb微服务框架服务如何自定义返回状态码?A: @Override @RequestMapping(path = "/sayhello",method = RequestMethod.POST) public String sayHello(@RequestBody Person person){ InvocationContext context = ContextUtils.getInvocationContext(); //自定义状态码 context.setStatus(Status.CREATED); return "Hello person "+person.getName(); } CopyQ: ServiceComb body Model部分暴露A: 一个接口对应的body对象中,可能有一些属性是内部的,不想开放出去,生成schema的时候不要带出去,使用: @ApiModelProperty(hidden = true) CopyQ: ServiceComb框架获取远端consumer的地址A: 如果使用http rest方式(使用transport-rest-vertx依赖)可以用下面这种方式获取: AbstractProducerContextArgMapper httpRequestCreator = (AbstractProducerContextArgMapper)invocation.getHandlerContext().get(RestConst.HTTP_REQUEST_CREATOR); if(httpRequestCreator != null){ HttpServletRequest req = (HttpServletRequest)httpRequestCreator.createContextArg(invocation); System.out.println(req.getRemoteHost()); } Copy实际场景是拿最外层的地址,所以应该是LB传入到edgeservice,edgeService再放到context外下传递。Q: ServiceComb不支持泛型A: 明确不支持,需要修改接口,接口修改后需要修改版本号,以免consumer还是使用旧的版本。Q: ServiceComb对handler描述A: consumer默认的handler是simpleLB,没有配置的时候handler链会使用这个,如果配置了handler,里面一定要包含lb的handler,否则调用报错,需要在文档里面进行说明。