分类: Uncategorized

  • 从简单日志到全链路日志 我们应该怎么打日志

    自从团队自研全链路日志系统上线后,一直想分享一下本人对日志系统的一些感受与记得,今天正好是周未,仔细回想了一下有关日志的点滴,因为涉及到全链路日志的概念,由于我打算从非全链路日志(普通)到全链路的演化路线做一次分析,就打日志关系的一次业务问题做一些简单的案例剖析。请搬个小凳子,开场了。

    非链路日志(普通日志)

    如果没有链路的概念,那恭喜,您正在使用普通的日志。普通的日志没有链路标识,不同请求的日志可能穿插在一起,查看的时候不太好串起来,分析日志有点点眼花缭乱。尤其是出现线上问题的时候,面对一团无序的日志,心急如焚。如果站点业务机有10台,定位日志的范围,也成为一个不太愉快的时候。若是多线程的服务日志,日志穿插得眼花缭乱。非链路日志(普通日志)在实时排查问题的过程中,存在的最大问题就是定位分析问题,简单的示例如下图,日志穿插在一起,不易分析同一个请求的情况。

    我收到一个请求,参数是
    我收到一个请求,参数是
    我收到一个请求,参数是
    我收到一个请求,参数是
    我收到一个请求,参数是
    用户账号BBB未认证

    单链路日志

    当我看到有同事使用GUID将日志请求串在一起的时候,我就这应该算是单链路日志了。站点的单次请求或服务的业务操作日志能够很好的被标识出来,在分析日志的时候,需要搜索同GUID的日志,请能定位到一个请求或作业的日志,不用提心其他日志的干扰。单链路日志对于分析单个站点或单个服务的日志情况,还是很有帮忙。我们已经能从日志中挑出日志,专注于重点日志。

    请求3fba452e-d9c9-45ee-96cb-19280fa59673 我收到一个请求,参数是
    请求b3a45dec-7667-4822-b7b9-7db1eec11a8b 我收到一个请求,参数是
    请求3e2f3851-9491-4f97-a47c-53d1001278ba 我收到一个请求,参数是
    请求6180a2f7-d9bf-4612-9d23-c5e6d46a079d 我收到一个请求,参数是
    请求26a9d771-f2f3-47fa-b810-d3071a1d98ca 我收到一个请求,参数是
    请求3fba452e-d9c9-45ee-96cb-19280fa59673 用户账号BBB未认证

    全链路日志

    全链路日志在单链路日志的基础上进行跨站点,跨服务逻辑的日志追踪。分我们排查问题的时候,往往是一个完整业务排查,不单是涉及一个站点的,可能需要顺藤摸瓜,一点一点回溯。单链路日志 对此就无能为力了。所以引身出了全链路日志,我们需要为每个完整的请求分配一个追踪id,称之为TraceId,这个追踪id将在业务站点间流转,将业务日志串起来。当我们查看日志的时候,可以完整得看到业务日志的流转明细。同样的道理,服务日志在入口处,也将分配一个完整的TraceId,标识出完整的日志。

    站点A
    TaceId 2ad28f58-858c-47c0-8875-e2e9db4ff24b 请求3fba452e-d9c9-45ee-96cb-19280fa59673 我收到一个请求,参数是
    TaceId 2ad28f58-858c-47c0-8875-e2e9db4ff24b 请求3fba452e-d9c9-45ee-96cb-19280fa59673 用户账号BBB未认证
    
    站点B
    TaceId 2ad28f58-858c-47c0-8875-e2e9db4ff24b 请求3fba452e-d9c9-45ee-96cb-19280fa59673 用户账号检查

    针对于全链路日志,我们应该采用TraceId将跨站点的日志打上标记,对服务内部的日志转流也同样的道理。通过GUID标记好的日志,可以通过日志收集系统,FileBeat抓取到Kafka,LogStash从Kafka消费送到ES,我们DIY一个全链路日志查询系统,在出一线上问题的时候,快速的定位出完整的业务日志,高效的排查问题。今天本想分享如果打业务日志,写着写着就变主题了,下次再找机会分析打业务日志的经验。关于日志收集系统的搭建,也是另外分享。

  • 支付宝踩坑记 | 更新手机安全支付产品密钥必踩

    时间的轮回就像无息的风声,嗖的一下就离首次接入支付宝手机安全支付产品有好多年的光景。这个时候,接到一个紧急需求,需要更新支付宝手机安全支付产品密钥。密钥是RSA密钥,意味着我需要生成一对商户的私钥、公钥,将商户公钥提供给支付宝,再将支付宝的公钥拿到手。凭借接入支付宝的丰富经验,直接掉坑里,因为这么坑太坑了,且看我慢慢写。

    一、支付宝新旧产品变迁,支付宝bug无情打脸

    原签约的支付宝安全支付产品时间比较早,当时估计支付宝的开放平台还没有“诞生”。出于于产品兼容性的问题考虑,大概明白这个产品属于老产品,更新密钥不是在开放平台的应用里。自信满满的帮同事去更新密钥,被支付宝无性的打脸!

     

    提示语定格在“系统异常,请稍后再试”!

    二、让人无语的机器人客服时代

    每次与支付宝打交道都有一种想吐血的节奏,支付宝客服不知道哪里来的自信,总会将我引导到一个机器人客服系统,答非所问,提工单,工单让我找商服,找到商服,商服就是一个自动回复机器人。技术人工客服问半闰,又给我导向了商服,商服又是一个没完没了的自动回复,真的把人气得要吐血。什么AI什么智能机器人,都是忽悠人。若非工作需要,把阿里系的所有东西全卸载都不解气。技术 人工客服唯一有用的一点就是,回复了一个问题,在哪里更新手机安全支付产品密钥,只有支付宝的人才知道,到底是什么产品,到底哪里是密钥更新的,这个答复,还是不错的。于是,我求证了一个密钥的问题,到底是使用java版密钥,还是非java版密钥,客服答复我,使用什么语言就使用什么密钥。听起来是那么的开心,我感觉不会掉坑里了。

    三、支付宝支付密钥系统BUG确认

    在我满腔怒气不受控制的情况下,我自己在钉钉群里圈了支付宝的对接人,将支付宝后台报错页面发过去,把人工客服答复,把商户机器人答复统统发过去,直接告诉TA,我已经吐血了。我知道钉钉对接群里有很多人,很从同事,我也顾及不了这么多。从上午开始,到下午,换电脑、换浏览器、清缓存、简直就是被耍了一天。支付宝最终确认是自己的系统问题。于是拉了一个小群,让我配合他们进行进一步的排查与处理问题,我到是非常关心更新密钥的事情,于是就接着配合。

    四、一个低级的支付宝系统BUG

    原以为支付宝出现了重大的系统BUG,新旧产品有重大的兼容问题。实际上却是支付宝产品的调整。更新密钥要求先入驻开放平台,从支付宝排查的结果来看,当点击查看开发者公钥时,会提示“系统异常,请稍后再试”,实际的请求情况如下

    {"msg":"开发者未创建","stat":"failed","code":"PERMISSION_DEVELOPER_NOT_CREATED","redirect_url":"https://developers.alipay.com:443/dev/workspace/register?errorCode=PERMISSION_DEVELOPER_NOT_CREATED"}

    也就是,支付宝的程序员,在处理业务的时候,并没有正确进行提示,引导用户先去入驻开放平台,导致更新密钥的业务流程卡死了。

    五、小心翼翼的掉支付宝的坑里

    前面有提到为了防止生成密钥出问题导致我们的业务中断,特意向客服求证了密钥需要生成什么版本的密钥。在支付宝提供的密钥生成工具里,我们可以看如下图所示的提示。

     

    PKCS8(Java适用)、PKCS1(非JAVA适用)2个版本提示得很明确,Java或者非Java,我们的服务端是在使用.NET版本,那自然就得使用PKCS8(Java适用),而且客服也确认了,依据自身的开发语言选择。真的是防不胜防,神坑啊!生成PKCS1(非JAVA适用)密钥对,更新完,支付单妥妥的生成失败。通知支付宝的人出问题了,支付宝的人让我去截日志看问题排查问题,我直接跳过了。我想估计还得是使用PKCS8(Java适用),抓住下班前的时间缝隙,拦截了财务人员,更新到PKCS8(Java适用)版本密钥,正常了。就是这么无语的神奇。.Net使用PKCS8(Java适用)密钥,成功了!还好没有相信支付宝的人去找日志,真要是找完日志,估计财务都不在公司了,一个晚上无法支付收钱,相相都是恶梦!

    六、支付宝产品密钥防坑总结

    支付宝的产品可以划分为新老产品,老的产品采用用md5加密,也有采用rsa密钥加密(1024位)。老的rsa密钥在mapi网关产品密钥中管理。老产品是没有开放平台应用的概念,sdk调用也不需要传appId,新产品需要在开放平台后台配置,需要为每一个应用进行配置,sdk调用需要传appId。新产品密钥支付1027位、2048位。依据目前踩坑的经验来看,老产品的sdk采用的是PKCS8密钥,无论是java语言,还是.net语言都是使用PKCS8密钥。在更新密钥的时候,千万不能被支付宝提供的密钥工具所迷惑,老版本使用的是PKCS8,.Net也是使用PKCS8,支付宝的老版本demo就是这么提供!慎重,这是一个巨大的坑,一不小心,就会出线上生产事故,扣钱扣绩效,背黑锅,太容易掉坑里。

    七、跨部门沟通

    更新密钥是一件非常重要的事情,协调不同部门的人一起完成一件神坑不断的事情,非常虐心。大家都有手上的活,自然会影响到他人的工作。一点都不影响到别人,那是表面上的友好,其实换位思考也是,背着支付宝的黑锅来回找要验证码、要财务登陆,换浏览器尝试,打断了别人工作,换谁都会有点情绪。我的目标是将支付宝手机安全密钥更新好,别人开心不开心,不管,这是工作,有点耍赖了!人在江湖啊!

    八、与支付宝沟通

    有支付宝的地方就有江湖!与支付宝的沟通,是非常虐心的工作,没有人愿意干这种事情,就像一只足球,被支付宝从钉钉踢到在线客服,被踢到技术在线客服,被踢到商服在线客服。如果对方能解答问题还好,问题是对方是一个机器人,答非所问。工作没有进展,整个人都不好了。支付宝非常精明的运用了机器人客服,将客户做了一次过滤,基本上小客户就是没有服务的,机器人纯答非所问。同时,支付宝也有一些“灰色”的业务是不会在客服系统里回复的,但是支付宝会有一句让人会意的让人沉思的答复“xxxx,请拨打….”。我非常不喜欢打阿里系的电话,非常抗拒,我知道电话里没完没了的等待,那怕是一秒,都感觉是一种煎熬。

    8.1 戏如支付宝

    与支付宝的沟通技巧在于,能联系客服经理的,优先联系客服经理。如果客服经理将自己导向在线客服,也不要生气,我们知道在线客服就是浪费时间的,但是这个戏还是要演,把在线客服答非所问的截图发给客服经理,同时,可以提工单,发邮件。因为客服经理可能答复不上来,就会拉技术进来,当技术拉进来之后,基本上问题就能比较快的解决了。

    8.2 老接口文档索取

    有不少支付宝老产品已经没有公开的入口了,有的老接口文档如果能搜索到,那就是见鬼了,搜索到了,估计也会有一个收费码,要求付费10块钱才可以下载。对于老接口文档,可以向客服经理要,一定要提供签约的pid,具体的接口名称。一般大客户会有此服务,如果连客服经理都没有,说明不是支付宝的重要客户,基本上只有冷冷的机器人服务,你说什么都是很nice的自动回毛复,直到你放弃。

    能在财务下班前更新好支付宝手机安全支付产品密钥,虽然过程是那么煎熬与不顺,想想事办成了,还是有些开心。我跟同事聊了聊,觉得这个密钥更新是一个必踩的坑,想想就扎心,这么多同行要更新密钥,这么多同行要踩坑!如果有幸看到,希望你能收藏起来,好好看看,也许能避免一场无辜的线上支付事故!

  • 面向法务编程|如何对接支付宝新产品满足法务要求:与诈骗青年过招

    今天有法务部门的同事前来咨询,需要查询一些账号信息用于诉讼。看要求非常简单,就是需要查询支付流水单,找到支付方的具体信息,支付邮箱或手机号。这对于一个IT系统来说,已经融入了业务、商务、法务多个领域的需求。本文从面向法务编程的角度,分享支付产品对接心得,主要分析了支付宝新旧产品的在法务合规方面的差异,结合新产品的特征,设计了满足法务例规性要求的IT系统实现。

    对于一个公司而言,不仅是为正常用户提供服务,也要防范不法分子利用公司的平台进行诈骗,保护公司的名誉与声望。虽然不良青年占比很少,却是公司很为头疼的事情。支付产品一直是不良青年的切入点,与不良青年的斗争,建立在数据凭证上,每一笔支付流水的都是诉讼的核心凭证,凭证对应到具体的自然人,对助于公司进行司法诉讼,维护平台的声望,打击不法份子。

    支付宝新旧产品的差异在司法领域非常明显,以前的支付报文会有支付人的手机号或邮箱,平台收到用户的举报与投诉后,或者平台主动排查风险,可以透过支付宝手机号或邮箱进行回访确认,确保支付的来源合法,避免平台沦落为洗黑钱的工具。

    新版支付产品报文

    {"alipay_trade_query_response":{"code":"10000","msg":"Success","buyer_logon_id":"zh***@yue.ma","buyer_pay_amount":"1.00","buyer_user_id":"2088002249904873","fund_bill_list":[{"amount":"1.00","fund_channel":"ALIPAYACCOUNT"}],"invoice_amount":"1.00","out_trade_no":"YM191019000001987","point_amount":"0.00","receipt_amount":"1.00","send_pay_date":"2019-10-19 09:03:32","total_amount":"1.00","trade_no":"2019101922001404875701675750","trade_status":"TRADE_FINISHED"},"sign":"H7QRYPzYhrli7a68RHNgHswVjnbG0Axu+s9vFof4qjBTMMVhDc8YgtEmd9OkABCDJggO0QCq+MgnFmS+hc6r3TZezGHkDHoyv/PjA9JZlj6atIrqbMGiiM0UyZibVfcC9lfSzZkbJFFFCkaXHTuShsilVrrkktUQyz+nW4zmnEOI5Rf/OohaK0gNOhjCv2f3WjfrxKgH22dRVXKT0V+KWudYIekI9ZW5vIkrPfDhhG7xP8hfcfHqOW3I8nc8+GuJUgyDsNpL8MRojULehMq/MPx1VZPi7GKqTitrqqSio4OK2xOxzMHEw9huOmOewQTVRWkwDV4jf0H/1pWRDSi9g=="}

    关键的支付宝账号被打码,在法务实践中,使用起来不方面,而通过法院调向支付宝调取买家信息,流程上自然有些不便。旧新支付宝产品,则不同,能直接查看到支付方的手机号或邮箱,对于已经升级到新版支付宝的企业来讲,法务事宜处理,成为困境。如何解决支付宝新版产品造成法务的被动性呢?

    我们能明确的要点在于,对于每一笔支付,我们需要记录下来用户的支付宝手机号或邮箱,让t每一笔支付的数据凭证完整可查,可在诉讼环节见中被印证,可在风控环节中起到追溯、核对作用。

    转变立即支付到授权后立即支付

    通常我们都想让支付越快越好,从司法有角度,我们不仅需要用户完成支付,还要知道是谁在支付,是否存在诈骗行为。对于大量使用他人支付宝账号进行充值的用户,我们可以圈定为可疑用户,在可疑用户中,我们可以结合用户的其他要素定性充值行为是否合法。公民信息是受法律保护的,在支付的过程,我们需要通过支付宝开放平台的授权登陆功能,让用户完成授权,再到支付环节,从而在合法合规的前提下,建立用户支付数据的完备性。

    法务是企业不可获取的护航部门,合法全规维护公司平台的正常运营,防止不法份子占孔子洗钱诈骗。法务需求穿插在 IT系统的每个角落。欢迎分享你的面向法务编程经验!

     

  • 最高级的编程方式:面向商务编程

    我们熟悉面向过程编程,也了解面向对象编程,在我们日常研发的过程中,往往需要我们采用编程手段将一些固化的业务逻辑采用代码的方式程序化。我们能很好的完成一个又一个新功能,还能随着业务的增长,不断的调整代码适应新的业务。

    然而有的时候,我们会发现,我们所掌握的面向过程编程与面向对象编程,解决不了我们编程中的困境。于是,通过引入几个真实的案例,介绍一下面向商务编程的方式与优点。

    真实案例一:对接阿里短信

    从短信对接的历史来看,通常都是传手机号与短信内容,阿里的玩法改变成了手机号、短信模板、参数。依据传统的做法,我们需要为两百多个短信模板配置阿里短信模板,还要做参数映射。依据阿里短信模板的审核流程来看,基本上是没有尽头的项目了。短信内容审核老是被打回来,参数不能过多,完全是一个无底的黑洞。针对我们业务的短信,要转化成阿里的短信参数,挑战还是很大,改造切入点还不少,还不能完全确保万无一失,使用维护管理都是一个挑战。采用面向商务的编程方式,由商务出马,结果一切变得那么顺利,谈妥一个万能参数,兼容了我们的短信平台,无需切入修改代码,新增一个短信服务商的实现。

    真实案例二:网银直连

    很多人以为网银直连一个技术问题,一直在寻找技术解决方案,其实网银直连、转账到银行卡等产品,都不是技术问题了,而是商务问题。所谓的大客户服务,就是别人享受不了的服务,你却能享受。这不是一个技术领域的问题,而是商务之间的互动。偶尔有人问我网银直连怎么接,我都感觉就像一个诡异的灰色游戏。

    真实案例三:支付费率

    传统的编程方式是不需要考虑支付费率的,无旨是一个冷凉凉的参数。面向商务编程,会要考虑,一年流水多少,5个点一年能省多少钱。一个简单的例子,如果率费是1%,一年200亿流水,手续费是多少?如果率费能到0.5%,又能省多少?

    真实案例四:短信监控

    一般我们接入短信,就是简单的把短信送到运营商,然后就了事了。如果我们按面向商务编程的思维方式再思考一下,月底怎么对账?哪条短信成功了,哪条短信失败了?这钱花得冤不冤?

    传统的编程思维方式倾向于实现,面向商务编程,倾向于优化成本,不拘泥于自身的研发,也关注于与合作伙伴的商务谈判与技术支持,同时更关注商务价值的实现。我们不仅是一名程序员。

  • 凌晨半夜短信通道异常,乙方如何答复?

    作为甲方,我们经历一场凌晨短信通道异常的煎熬,这个时候正是多数人睡梦中。我们却睡梦中惊醒。短信通道异常,用户无法收到短信,我们非常被动。出了什么问题,哪个环节出了问题,我们如何处理?见到问题后,我们首先排查了自身短信服务的情况,均无问题,于是问题的重点在短信服务商出了问题。下面详细介绍一下我们排查问题的关键要素与处理方案,最后我们来分析乙方如何答复,阐述了为什么我只打50分,连及格分也没有给。

    短信流水

    我们能看到的短信流水是乙方提供的流水,仅代表了短信被乙方收到,乙方将短信送到移动电信联通运营商的过程与结果,完全是在黑盒子里。比较尴尬的是乙方不提供短信回执,整个流程就变得不可监控,无法预知了。我方收到的流水均是乙方返回的成功流水,对于短信的真实发送状态,完全没有了参考意义。

    紧急预案

    非常幸运的是我们接入了多个短信平台,对于某个短信平台出现异常问题,我们采取了快速的通道切换措施。面对紧急情况,我们关心的是业务如何快速恢复可用状态,短信服务商如不能给出一份具有负责感的短信故障分析报告,估计是很难切回去。表面上大家一团和气,似乎不是什么大问题,作为甲方,一群人半夜无眠,也许都没有人愿意再切回去了。

    短信数据核对

    合作的过程,彼此的信任是非常重要的,短信无法进行监控,无回执,非常的致命。通过核对短信提交到乙方时间、短信提交到运营商时间、运营商回执时间,回执状态这些关键的短信数据,分析出了事故的发生时间,与处理耗时。这些在乙方的故障报告中均无所体现。所以,做为甲方,要看数据说话,从数据看自己关心的点。

    乙方如何答复

    出现这种事故,乙方如何争取甲方切回通道呢?一份详尽的报告与整改措施是必不可少的,切记,不要一份甩锅的事故报告,把自己的责任推得一干二净的。至少从一个甲方的角度考虑,问题这么久,乙方有没有机制自动发现问题自动修复。如何避免重复问题的产生?若答复踩不到要点,让甲方爸爸怎么安心开启通道。

    后记

    做为甲方爸爸,我在想什么,乙方要好好想想,现在短信平台太多了,竞争那么激烈,我们程序又能做通道切换,服务不好,就切走了。估计乙方看不到我写的东东,还在纳闷,为什么给了一份“专业”的事故报告,我们也没有在群里生气,通道却没有再切回去。

  • C# .Net MVC 下的 [OutputCache(Duration = 300)] 缓存穿透问题

    近期做压测优化时,特意选用了无侵入式代码注解方式[OutputCache(Duration = 300)] 对接口做了5分钟缓存。依据业务预期,5分钟的缓存能确保我们的接口顺利通过压测。就在满怀信心等着通过的报告时,却被打脸了。

    报告显示,在前2分钟,接口返回都正常无错误,接下来就出现了错误返回。仔细想想,这个问题在于,缓存失效的一瞬间,大量的请求穿透过去,导致请求直接压到了需要保护的后端服务。

    于是,采用lock的方式,防止缓存击穿!

    protected static object sysncObject = new object();

    // 开缓存了,防止缓存失效的时候发现穿透效应 lock (sysncObject) { //原来的业务逻辑 }

    经过lock处理后,压测顺利通过。目前没有发现,OutputCache的Cache保护措施,只能使用DIY进行击穿保护。