偶遇的dubbox小坑

公司新做的项目,用了一个让人又爱又恨dubbox,引用dubbox的简介:

支持REST风格远程调用(HTTP + JSON/XML):基于非常成熟的JBoss RestEasy框架,在dubbo中实现了REST风格(HTTP + JSON/XML)的远程调用,以显著简化企业内部的跨语言交互,同时显著简化企业对外的Open API、无线API甚至AJAX服务端等等的开发。事实上,这个REST调用也使得Dubbo可以对当今特别流行的“微服务”架构提供基础性支持。 另外,REST调用也达到了比较高的性能,在基准测试下,HTTP + JSON与Dubbo 2.x默认的RPC协议(即TCP + Hessian2二进制序列化)之间只有1.5倍左右的差距,详见文档中的基准测试报告。支持基于Kryo和FST的Java高效序列化实现:基于当今比较知名的Kryo和FST高性能序列化库,为Dubbo默认的RPC协议添加新的序列化实现,并优化调整了其序列化体系,比较显著的提高了Dubbo RPC的性能,详见文档中的基准测试报告。支持基于Jackson的JSON序列化:基于业界应用最广泛的Jackson序列化库,为Dubbo默认的RPC协议添加新的JSON序列化实现。支持基于嵌入式Tomcat的HTTP remoting体系:基于嵌入式tomcat实现dubbo的HTTP remoting体系(即dubbo-remoting-http),用以逐步取代Dubbo中旧版本的嵌入式Jetty,可以显著的提高REST等的远程调用性能,并将Servlet API的支持从2.5升级到3.1。(注:除了REST,dubbo中的WebServices、Hessian、HTTP Invoker等协议都基于这个HTTP remoting体系)。升级Spring:将dubbo中Spring由2.x升级到目前最常用的3.x版本,减少版本冲突带来的麻烦。升级ZooKeeper客户端:将dubbo中的zookeeper客户端升级到最新的版本,以修正老版本中包含的bug。支持完全基于Java代码的Dubbo配置:基于Spring的Java Config,实现完全无XML的纯Java代码方式来配置dubbo调整Demo应用:暂时将dubbo的demo应用调整并改写以主要演示REST功能、Dubbo协议的新序列化方式、基于Java代码的Spring配置等等。修正了dubbo的bug 包括配置、序列化、管理界面等等的bug。注:dubbox和dubbo 2.x是兼容的,没有改变dubbo的任何已有的功能和配置方式(除了升级了spring之类的版本)

虽然我更喜欢用 spring 全家桶,但是项目架构选择,也不是我能决定的。

其实,个人理解的dubbox就是在alibaba放弃dubbo之后,dangdang捡起来优化了下代码,然后加了一层restful实现,但是这个实现,用着用着,在某一天,发现了一个小小的坑,然后我就顺着这个小坑,就顺便理了一下这层restful的实现逻辑。

由于之前一直习惯用spring mvc开发,接收前端表单数据的时候,习惯用application/x-www-form-urlencoded的方式去接收数据,所以在没有研究dubbox的实现的情况下,在provider中,启用了application/x-www-form-urlencoded,从而导致consumer发起调用,传输中文数据的时候,出现乱码的情况,而且这个乱码的情况还是一时会发生,一时不会发生,很是怪异。

翻看dubbox的代码,发现,其实dubbox内部在定义接收的content-type的时候,已经为我们提前定义好兼容的content-type,而我偏偏选择了application/x-www-form-urlencoded从而导致了BUG的出现

而就算是启用了不支持的content-type,为什么就会导致乱码呢?其实在于dubbox在dubbo原来的基础上,封装了restful,而restful的实现,用的jbossresteasy全家桶。


翻看dubbox的RestProtocol(restful实现),可以发现 resteasy不仅仅只是提供提供注解支持,也能提供目标restful url与对应的spring service的代理调用。


其实,看了代码之后发现,为什么会产生乱码的原因主要原因在于发起http访问的时候,用的是DefaultHttpClientDefaultHttpClient内部使用的content-charset,居然是ISO-8859-1...

而当我使用application/x-www-form-urlencoded;charset=utf-8就会出现编码不一致的问题,从而导致乱码的出现。

而为什么会出现一时出现乱码,一时不出现乱码呢,原因在于当provider,同时以dubbo,rest发布的时候,基于负载均衡,轮询访问的节制,当出现一次调用provider使用rest方式调用,而另外一次调用是通过dubbo rpc方式(Netty)调用的话,就会出现一时乱码,一时不出现乱码。

以上是个人对于遇到的问题的一次问题排查以及理解,虽然最后也只能通过规避的方式解决问题(毕竟是商业项目),但是起码对于dubbox有了一些了解,也不会那么云里雾里了。

附上整理的调用图例,画的比较土。-,-


你可能感兴趣的:(偶遇的dubbox小坑)