Mars 常见问题

garryyan edited this page Dec 27, 2017 · 35 revisions

通用问题

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-加密使用指引

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-r11c 以上,强烈建议使用 ndk-r11c(官方下载旧版本方法:下载最新版本的 url 中 ndk 版本号直接改为想要的版本号即可)。如若仍然不能解决,请联系我们。

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启动失败

  1. 当下载gradle过程中出现javax.net.ssl.SSLException: SSL peer shutdown incorrectly时,是由于无法连接google service导致,请确认命令行已翻墙。
  2. 当下载gradle过程中出现java.util.zip.ZipException: error in opening zip file时,是由于下载的gradle.zip文件出现错误导致,请删除前面提示路径下的zip文件,重新启动server,这时会重新去下载。
  3. 当启动server过程中出现jetty 或 netty启动failed,请使用./gradlew :server:jettyRun --stacktrace或./gradlew :server:nettyRun --stacktrace启动查看具体出错信息,如果出现address already used/bind,说明端口号被占用,jetty默认8080,netty默认8081,如果想要修改端口号,请在server工程中搜索端口号数字,修改。

SDT常见问题

  1. SDT是由STN在网络连接、收发失败过程中根据实际情况,自启动的网络检测工具,目前并没有提供给上层主动检测的接口
  2. SDT源码完整,未提供主动检测的功能,是我们认为目前手段非完整性还需要完善,目前包含tcp心跳测试、http连接测试、ping、dns测试

更多的使用范例,大家请仔细阅读Sample。使用过程中有任何问题或建议,欢迎联系我们!

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.