Mars 常见问题
Mars sample 代码可以直接用到生产环境中吗?
不建议用到生产环境中,这部分代码是未经过微信验证的 demo 代码
Mars 包括服务端吗?
Mars 只是一个客户端的解决方案,并不包括服务端的代码。 如果使用 Mars 中的 STN,需要客户端和服务端对齐好协议。
Mars 中的 STN 和 Xlog 可以在一个应用多个进程中使用吗?
STN 不可以,也不建议,如果你执意这么做,请给getAppFilePath的回调返回不同的路径。 Xlog 可以,只需要你传参数的时候日志的前缀不要传相同的就行。
如果我已经有现有服务器端了,客户端想使用 Mars,需要服务器做什么工作?
如果你已经深入了解了 Mars,感觉自己适合使用 Mars的,需要先理解长短连协议和加解包的区别。不论之前使用的哪种方式,长短连的协议是必须有的,你需要参照自定义扩展把长短连协议和服务器端对齐, 至于加解包逻辑是在 Req2Buf 和 Buf2Resp 回调中做的,给上实现就可以了。关于长短连协议的理解和 req2Buf buf2Resp 的理解可以看一个例子:就像你用 HTTP 发一个 json 数据 HTTP 就类似 Mars 的长短连协议, json 的组装和解析就是 req2Buf 和 buf2Resp 来做的
如果我已经有现有服务器端了,客户端想使用 Mars,客户端需要注意什么?
longlink_packer.cc中的自定义需要注意。心跳包的cmdid一定要和服务器的对应上,否则可能发生心跳包超时导致长连断开。longlink_complexconnect_need_verify的含义是如果设为 true 经过心跳包验证的连接才认为是成功的连接。如果你的长连接建立连接后第一个包必须是验证包,该函数的返回值一定要设为false。 长连的鉴权是会回调GetLonglinkIdentifyCheckBuffer这个函数,实现即可,记得处理回包:OnLonglinkIdentifyResponse,需要区分开长连接的鉴权和用户的登陆。长连的鉴权只是用来表示这个长连接是某个人的,不要用来做登陆功能。 强调:需要注意,mars长连的请求包和回包的对应关系的条件是seq一样,所以服务器对请求的回应要保证seq一样,或者可以自己在longlink_taskmanger.cc里修改(不推荐)。
如果我们的客户端不使用域名使用多个IP的情况下怎么使用Mars?比如:客户端会 hardcode 一批 IPs1,用户连上服务器服务器会下发一批 IPs2。
目前 Mars 长连提供设置 host 信息的接口是 setLonglinkSvrAddr 只支持设置单个域名,会在 Mars 中进行解析 IP。但是这个接口不能重复调用,只会以最后一次调用为准。所以如果你们只有 IP 列表没有域名的话,例如上面的场景,我们建议的解决方案:把 IPs1 通过 setBackupIPs 设给Mars,随机从 IPs1 中选择一个 randomip 当做 setLonglinkSvrAddr 的 host 设给 Mars,在 onNewDns 回调接口中当发现是 host 是之前的 randomip 时把 IPs2 返回给 Mars。 这几种IP的优先级请参考 Mars 常用术语。
使用了Mars发现接收比较大的数据比较容易失败,是什么原因?
Mars 主要针对信令数据而设计的,如果一个数据需要接收时间比较长,会被认为超时,建议单个数据包不要超过 64 k
我在自己机器上启动 demo 中的 server, 为什么一直在 Downloading gradle,卡了很久。
运行server前,如果你本机没有安装过gradle, 会自动安装。如果一直卡住,建议翻墙或者更换VPN试试。
一个任务在 Mars 中流转的流程是怎么样的?
一个任务以 startTask 为开始,以 onTaskEnd 为结束。 首先调用 startTask-> 如果你的任务设置了 limit_flow=true 或者 limit_frequency=true 会进行防雪崩检测 -> 如果设置了need_authed = true 会回调 makesureAuth 询问是否已经是登陆态,不是的话需要上层异步去登陆,底层任务会等待-> 回调 req2Buf 进行打包-> 发送 ->如果send_only = false 就是需要等待回包, 不需要等待的话会直接调用 onTaskEnd -> 收到回包回调上层 buf2Resp 进行解包 -> onTaskEnd。关于长短连协议的理解和 req2Buf buf2Resp 的理解可以看一个例子:就像你用 HTTP 发一个 json 数据 HTTP 就类似 Mars 的长短连协议, json 的组装和解析就是 req2Buf 和 buf2Resp 来做的
Mars 中哪些模块是可以独立使用的?
Xlog 是可以独立使用的,SDT 暂时不可以单独使用。SDT的自动逻辑会被STN自动触发。
Xlog 文件怎么查看?
Xlog 目录下存放的 mmap2 文件有什么用?
mmap2 文件为 Xlog 的缓存文件,不用关注,真正的日志内容在以 xlog 为后缀的文件中。
为什么我使用了 Xlog 会感觉应用卡顿?
使用 Xlog 的时候请尽量不要使用同步模式,同步模式会直接写文件,同步模式主要为了调试环境用的。推荐的模式为异步模式,INFO级别。
Xlog 对日志文件的自动清理逻辑是怎么样的?
每次启动时会删除过期文件,只保留十天内的日志文件(该值定义在appender.cc中的 kMaxLogAliveTime ),所以给 Xlog 的目录请使用单独目录,防止误删其他文件。目前不会根据文件大小进行清理。如若想自定义清理逻辑请自行更改appender.cc中的 __del_timeout_file 函数。
Android
执行 python build_android.py 编译错误
先区分是否是 python 的语法错误,如果是,请先确保 python 版本为2.7x, 如果是编译过程中的错误,请确保使用的 ndk 版本为 ndk-r16b 以上,强烈建议使用 ndk-r16b(官方下载旧版本方法:下载最新版本的 url 中 ndk 版本号直接改为想要的版本号即可)。如果你的平台是 Windows 系统,还需要安装 cygwin,并务必要安装其中的 make, gcc gdb。 然后把 cygwin 的 bin 目录配置到环境变量中的 PATH 中。如若仍然不能解决,请联系我们。
Debug版本下没问题,release版本下报 java.lang.UnsatisfiedLinkError
release版本下是否混淆了代码,如果混淆了把mars相关的代码keep下:
-keep class com.tencent.mars.** {
public protected private *;
}
或
-keep class com.tencent.mars.xlog.** { *; }
-keep class com.tencent.mars.comm.* { *; }
-keep class com.tencent.mars.app.* { *; }
-keep class com.tencent.mars.stn.* {*;}
如何调试
目前 Mars 的项目组织方式在 Android 平台下调试并不友好,建议通过 xlog 输出的信息进行排查问题。
为什么我的 xlog 文件使用 decode_mars_log.py 解出来有很多错误存在?
目前 xlog 不支持多个进程写到同一个文件中,先确认是否是因为多个进程把日志写到同一个文件所致。
打开 xlog 的 sample 报:…………libmarsxlog.so exists or that its paths is correct……
如果出现下图: 请重试直到这个 tips 消失。如果一直重试不成功可以尝试把下面的代码先注释掉再 Try Again。成功后再取消掉:
多进程应用使用 Mars 应该注意什么?
调用 native 函数前一定要确保包含 native 函数的实现的 so 是在本进程中,如果不在,可能需要跨进程调用或者先 load so。
native 代码的 crash 监控应该怎么做?
mars 是经过微信验证过的,稳定性方面是有保证的。不过你依然可以有自己的 crash 监控模块。 native crash 捕捉原理是基于 linux 的信号机制进行堆栈回溯。具体实现可以参考 Android 内核源码中 libunwind 和 libcorkscrew。不建议使用 dlopen 进行调用,因为安全问题谷歌会在不久的将来禁止 dlopen 系统库(个别库除外)。 第三方 crash 捕捉服务推荐使用 Bugly
xlog有大量的 signal 7 (SIGBUS), code 2 (BUS_ADRERR)
crash, 什么原因导致的?
#204 #249。
注意:日志不要放在这个目录,不然就太占 data 空间了。缓存目录类似日志目录,要单独目录,防止清理逻辑误删其他文件,而且缓存目录一定要是data下的私有目录,可以使用 /data/data/packagename/files/xlog/
为什么长连断之后很长时间都不去尝试连?
考虑用户的电量和流量,长连的连接策略会根据应用的前后台而不同。 请先确认是否忘记在前后台切换时主动调用
BaseEvent.onForeground(boolean);
iOS/OS X
为什么 Apple 系平台没有通过 CocoaPods 来管理类库?
我们一直认为合适的才是最好的。Mars 是有很多子项目,每个子项目是单独的编译配置,这点 CocoaPods 做不到,因为 CocoaPods 是一个项目文件,如果引入 CocoaPods 就必须多维护一套编译脚本,而且丢失了我们目前多个子项目的优势,所以并不适合我们的项目。
打开 Mars 时,为什么有时某个子项目无法展开?
请确认是否已经在 xcode 中单独打开了该子项目,如果已经单独打开,请先关闭,再打开 Mars。
编译时为什么提示 "string not found" 或其他 C/C++ 头文件找不到的错误?
请确认直接调用 C/C++接口的 Objc 源文件是否都是 .mm 后缀,如果不是,请把 .m 后缀改为 .mm 。
为什么编译 demo 时 xcode 的进度条一直没进度,感觉被卡住了?
为了保证使用的 Mars 代码是最新代码,每次编译 demo 都会通过 Run Script 编译 Mars。 如果已经编译过一次,可以把 Run Script 移除,防止重复编译。
为什么使用脚本编译的 framework 链接运行没问题,但是调试过程中会中断言?
使用编译脚本编译的 framework 是 release 版本的,即使中断言,也只会打一行日志,并不会导致程序退出,调试过程中生成的 Mars 的库是 debug 版本的,中断言会导致程序退出。 中断言一般因为某些 callback 没有设置,或者 callback 中的某个函数没有实现,请结合堆栈进行分析。
为什么长连断之后很长时间都不去尝试连?
考虑用户的电量和流量,长连的连接策略会根据应用的前后台而不同。 请先确认是否忘记在前后台切换时主动调用
mars::baseevent::OnForeground(isForground);
Sample Server启动失败
- 当下载gradle过程中出现javax.net.ssl.SSLException: SSL peer shutdown incorrectly时,是由于无法连接google service导致,请确认命令行已翻墙。
- 当下载gradle过程中出现java.util.zip.ZipException: error in opening zip file时,是由于下载的gradle.zip文件出现错误导致,请删除前面提示路径下的zip文件,重新启动server,这时会重新去下载。
- 当启动server过程中出现jetty 或 netty启动failed,请使用./gradlew :server:jettyRun --stacktrace或./gradlew :server:nettyRun --stacktrace启动查看具体出错信息,如果出现address already used/bind,说明端口号被占用,jetty默认8080,netty默认8081,如果想要修改端口号,请在server工程中搜索端口号数字,修改。
SDT常见问题
- SDT是由STN在网络连接、收发失败过程中根据实际情况,自启动的网络检测工具,目前并没有提供给上层主动检测的接口
- SDT源码完整,未提供主动检测的功能,是我们认为目前手段非完整性还需要完善,目前包含tcp心跳测试、http连接测试、ping、dns测试