分类归档:架构设计

JVM GC问题排查手段

最近生产环境上出现过两次由于JVM参数设置不当导致的频繁FGC的问题,现在做个简单的记录.

  1. 首先查看GC日志,观察每次FGC的频率以及各个区的回收情况
  2. 然后再配合使用jstat与jmap查看是否有泄露问题,分析内存泄露最佳组合就是jamp dump + MAT,先dump内存,然后MAT分析来定位问题,要jmap -heap需要慎用,在用cms gc的情况下,有些时候jmap -heap会循环输出,然后就卡死了
  3. 最后使用jstack排查各线程的状态,包括用户线程和虚拟机线程,同时结合Lock信息来检测是否发生了死锁和死锁的线程.
    ​另外在用top -H看到占用CPU非常高的pid时,可以转换成16进制后在jstack dump出来的文件中搜索,看看到底是什么线程占用了CPU

总之,GC问题是一个需要不断跟进的问题,它会随着业务与技术发展而不断出现,需要用到很多方法与经验.

Android-zxing使用总结

需求

最近三个月一直忙于@微卖客户端的开发,在开发过程中遇到各种各样的问题,虽问题一一解决但并没有很好的归类与整理,恰好遇到假期有时间由近及远的梳理一下,而条码与二维码的扫描则是近期遇到问题之一.好在android的迅速发展也带动了第三方开发者在此平台上的活跃度,从Github上我们几乎能找到各种常用的组件与工具包,而zxing也是解决条码与二维码的扫描的成熟方案之一.

zxing使用问题

  1. zxing最新版本是3.1.0,但是在实际使用过程中发现取景框与实际抓图高度存在偏差,导致经常不能正确识别条码,只是由于开发时间关系,我并没有直接去找原因,而是退而求其次选择了2.3.0的版本使用,果然问题消失了.
  2. 在zxing的使用过程中,官方自带的例子使用了很多我们不太需要的功能,而我的需求只是正确识别二维码与条码即可,当然能有开灯功能更好,而在使用这些功能完全可以将很多不用的模块剔除掉,从而关注我们自己的核心业务.
  3. zxing在例子中只提供了横屏解决方案,但我们的需求是需要竖屏使用,同样需要对zxing做点小改造.

阅读全文…

双色球背后的程序

突发奇想

首先这个题目有点大,但我实在想不出更好的标题了,这一切也是由于最近与小伙伴们讨论双色球,简单来说双色球就是一种排列组合小游戏,但又区别于全排列,它只针对数值而不针对位置,而其又区别蓝球与红球,那么我们很简单的就可以算出其全组合的可能数值,即红球33选6,33!/(6! * (33-6)!) = 1107568,蓝球16选1,全组合就是1107568 * 16 = 17721088,想一想这也确实很夸张,别说中头奖了,甚至中三等奖也是低概率事件,那么我们是否有办法提高中奖概率呢,个人认为肯定是有的,毕竟双色球只是一种伪随机.

程序实现

经过挖掘与分析,貌似能提高双色球中奖概率的条件有以下几种,例如红球分区,和值,跨度,奇偶比,质合比,012路比等等,那么我们可以将这类限制抽象成条件,但前提是我们需要将所有的组合全部列举出来,然后通过条件去缩小范围,这里我们有了第一个问题,即生成红球的所有组合,然后输出到一个文件里,代码看起来应该是这样

阅读全文…

游戏开发中的全环境配置文件管理

面临问题

游戏开发中我们常常会遇到一个问题就是测试环境下配置文件与生产环境配置文件不一致,当然最常用的就是在maven中指定不同的profiles然后分别打包,但是在游戏上线后这种方式就不太灵活,例如游戏上线后需要在特殊节日增加了一些新活动,但这种游戏逻辑已经内嵌至代码中,不必修改,往往只需要改几个配置就够了,同时本地开发是windows,osx,生产环境又是linux,加载路径也是千奇百怪,那么对于这种需求我们应当如何解决呢?

功能设计

  1. 区分开发,测试,生产环境
    这一点很容易理解,即划分好各环境沙箱,使其相互之间没有干扰,最简单易行就是使用spring中PropertyPlaceholderConfigurer来解决各配置的差异,同样你可以使用当然你也可以使用Spring Bean definition profiles,但这个功能支持需要使用spring 3.1以上版本.
  2. 提供统一的文件访问接口
    文件的使用者不应该把重点放在如何加载配置文件上,而是直接将文件封装成他需要的对象,这样我们就需要一个能解析各种文件的工具类
  3. 基于事件机制的加载触发
    配置文件加载不应该是显示的调用,而应该是基于事件机制,当在消息总线中抛出一个事件,那么各模块的配置文件加载器需要知道此时是否需要加载配置,而不用关心当前游戏服务器的状态.

阅读全文…

游戏开发中的定时器

面临问题

在游戏中我们经常会遇到定时器,例如从大方面来每日的零点,节假日双倍经验,boss刷新,从小方面来说回合制中该回合在多长时间内结束,战斗中buff/debuff状态时间,技能的cd时间等等都涉及到定时器,前一种我们实现方式比较多,例如最常用的crontab,quartz都可以实现,而后者更像一种闹钟,到时候就去唤醒一个事件.我们今天就先讨论了下后面这种”闹钟”如何实现.

设计实现

要使用闹钟我们首先想到的就是Timer,但在java 1.5后全新推出了ScheduledThreadPoolExecutor,我们用它来对Timer进行替代,其次我们需要定义一个间隔周期,让这个定时器每隔多长时间去跑一下,看看有没有什么任务可以执行,这个间隔不能太长,太长会导致某些任务触发不及时,但也不能太短,太短容易加重系统开销,我们暂定50毫秒走一次定时器,伪代码看起来像这样

阅读全文…