使用dubbo框架的一些坑记录

以下记录都基于dubbox的使用

1.autowired一个服务失败

服务引用配置<dubbo:reference interface="xxx">,明明就已经声明了xxx的服务,但service bean通过autowried引用,总提示xxx不存在,原因是xxx 服务少了id的设置,查看官网文档,dubbo:reference表签,id属性为必填项。但dubbo启动时却没有发出警告,导致问题被隐含了。

2.超时(timeout)与重试机制(retires)

dubbo通过设置短的超时机制+重试次数,马上将当前超时服务提供者provider切换到其他可用的provider,通过这种思路实现快速响应。但对于一些新增记录的操作来说,有可能因为设定时间内,provider无法响应,客户端执行n次重试,导致新增记录操作的请求发了n次,数据库里这时候保存了n条记录数据。暂时解决方式是将那些响应时间相对旧一些的服务,它的超时时间设置长一点,并将重试次数retries设置为0

3.timeout设置问题
最近发现用于设置默认值的标签<dubbo:consumer> 跟 <dubbo:provider>无法 为对应的标签<dubbo:reference>和<dubbo:service>设置默认值timeout。
不能进行全局配置,而只能单独在<dubbo:reference>和<dubbo:service>上设置timeout。
还在看源码找出问题.......,知道的麻烦告诉我一下

4.占用内存问题:

内存满了以后常见影响:
<ul>
<li>A.导致接口异常(如数据请求失败) </li>
<li>B.导致程序启动国漫</li>
</ul>

项目拆由原来单一个应用(可以看成单一个provider)按照业务功能便捷,拆分成好几个provider, 但不是全部都拆了出来,还保留了一个原始比较大的provider。

基本上每个provider 至少占用100M 的内存,有的还会占用300M,对于原始provider 会用上500M内存!!!

也就是说比如原来单一个provider 跑程序可能占用 500M以上的内存,经过拆分若干过以后,就会变成 500M + ( 100M~300M ) * N。

我们这边服务器配置比较低,基本上要两台服务器才能把所有provider部署下来,不然全部部署同一个服务器,最后一个启动的provider有可能因为内存满了,而加载很慢,从而影响整个应用服务不能正常运作。

PS:内存相关检测工具提示 top命令、jmap命令、MAT(memory analyzer tool)工具。

3.多个Provider更新维护脚本
关键词 : svn + maven + shell
另外一点:由于拆分了好多个服务,所以如果要一次批量全部更新的话,要在linux上不断的cd 、 nohup java -jar ......

A.svn搭建
搭建一个专门用来 存放各个环境(如开发环境、测试环境)的运行目录所需要的程序,包括provider, web部署目录。
更新的时候,先本地把包提交到svn ,然后登上运行的服务器进行svn checkout。
PS:如果是生产环境的包就不能这样做,有可能需要新建一个目录然后checkout。

B.运行脚本startup.sh
为每一个provider 编写startup.sh 脚本:
<pre>

! /bin/sh

jar=find . -iname "*.jar" -maxdepth 1
conf=pwd
conf=$conf/spring-config.xml
echo "using spring config file:$conf"
nohup java -Ddubbo.container=spring -Ddubbo.spring.config=spring-config.xml -jar $jar &
</pre>
放在maven 项目 src, 即与main 、test目录同一级:

dir.png

现在有了每个provider 的startup.sh了,为了一件启动,所以还需要写一个总运行的脚本,
startup_all.sh :
<pre>

! /bin/sh

echo 'please run this shell using command "source"'

echo "shell start...";

cur=pwd

modules=("providerA"
"providerB");

for module in ${modules[*]}; do

binpath="$module/bin/"

echo "$module starting..."

cd $cur;
temp=pwd

echo "cd $temp "

cd $binpath;
temp=pwd
echo "cd $temp"
./startup.sh;
done;
</pre>

由于开发环境或测试环境服务器内存不够,有可能要将不同的provider部署到不同的服务器上,这时就要把startup_all.sh 文件拆分成两个文件来运行。

C.Maven 处理
自动将所有项目输出目录 指向同一个 目录下,目录结构例如
buildAll
buildAll/ProviderA
buildAll/ProviderB
只需要在pom文件 build标签中设定directory的值即可
<pre>
<build>
<finalName>cn-jufuns-residences-origin-provider</finalName>
<directory>../../buildAll/${build.env}/${artifactId}</directory>
</pre>
其中${build.env} 可选的值为dev 、test、 production,分别表示开发环境、测试环境、生产环境。由parent 项目(定义所有子项目的依赖)里的pom 文件定义。

另外由于maven 输出包含一些多余文件,所以我利用maven resources插件将需要的文件 或目录 ,如jar,lib目录,properties文件,shell文件,拷贝到输出目录底下的bin目录:


dir2.png

maven 插件配置:
<pre>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>install</phase>
<goals>
<goal>copy-resources</goal>
</goals>

        <configuration>
            <outputDirectory>${build.directory}/bin</outputDirectory>
            <resources>
                <resource>
                    <directory>src/sh</directory>
                    <includes>
                        <include>*.*</include>
                    </includes>
                </resource>
                <resource>
                    <directory>src/main/resources/</directory>
                    <includes>
                        <include>*.*</include>
                    </includes>
                </resource>
                <resource>
                    <directory>${build.directory}</directory>
                    <includes>
                        <include>*.jar</include>
                        <include>lib</include>
                    </includes>
                </resource>
            </resources>

        </configuration>
    </execution>
    <!-- 拷贝lib目录 -->
    <execution>
        <id>copy-lib</id>
        <phase>install</phase>
        <goals>
            <goal>copy-resources</goal>
        </goals>

        <configuration>
            <outputDirectory>${build.directory}/bin/lib</outputDirectory>
            <resources>

                <resource>
                    <directory>${build.directory}/lib</directory>
                    <includes>
                        <include>*.*</include>
                    </includes>
                </resource>
            </resources>

        </configuration>
    </execution>


</executions>

</plugin>
</pre>
这里要主要这个插件一定要放到最后,所以要注意下phase 这个值。

4.聚合日志Flume 使用

A.版本升级
dubbo 官方原始版本,包括dubbox 使用的还是log4j 1.X版本,为了使用Flume日志器,需要将dubbo升级为log4j2 版本。
(如果直接使用log4j 1.X版本 + Flume Appender 会报异常,提示Flume Appender 不能占用当前线程进行工作,而log4j2 是支持异步日志器 AsyncLogger,所以升级到log4j2版本)
如果没记错,由于spring 3.x 对log4j2 版本不支持,所以同时也把spring 3.x 升级到4.0。

B.Flume搭建一些bug
配置好Flume以后,客户端log4j2 远程传送日志到Flume时,提示"拒绝连接",
百度了一下,说是avroSource 绑定IP 不能指定localhost 或127.0.0.1 或0.0.0.0,改了以后就正常使用了。下面是Flume properties配置文件信息:
<pre>
a1.sources = r1
a1.channels = memoryChannel
a1.sinks = fileRollSink

seqSource

a1.sources.seqSource.type = seq

agent.sources.seqSource.channels = fileChannel

avro source for log4j

a1.sources.r1.type = avro
a1.sources.r1.channels = memoryChannel
a1.sources.r1.bind = 172.16.3.213
a1.sources.r1.port = 44446

sink configuration

fileRollSink

a1.sinks.fileRollSink.type = file_roll
a1.sinks.fileRollSink.sink.serializer = TEXT
a1.sinks.fileRollSink.sink.directory = /opt/app_logs/
a1.sinks.fileRollSink.sink.pathManager = ROLLTIME
a1.sinks.fileRollSink.sink.pathManager.prefix = all-app-
a1.sinks.fileRollSink.sink.pathManager.extension = log
a1.sinks.fileRollSink.sink.rollInterval = 3600
a1.sinks.fileRollSink.batchSize = 100
a1.sinks.fileRollSink.channel = memoryChannel

loggerSink

a1.sinks.loggerSink.type = logger
a1.sinks.loggerSink.channel = memoryChannel

channels configuration

fileChannel

a1.channels.fileChannel.type = file

a1.channels.fileChannel.dataDirs = /Users/IssacChow/workstation/apache/flume/apache-flume-1.7.0-bin/datadir

a1.channels.fileChannel.checkpointDir = /Users/IssacChow/workstation/apache/flume/apache-flume-1.7.0-bin/checkpointdir

memoryChannel

a1.channels.memoryChannel.type = memory
a1.channels.memoryChannel.capacity = 1000
a1.channels.memoryChannel.transactionCapacity = 100
</pre>

运行脚本startup.sh :
<pre>

! /bin/sh

nohup ./bin/flume-ng agent -n "a1" --conf "./conf" -f "./conf/flume-conf.properties" &
</pre>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容