咖啡下沉市场激战:瑞幸、蜜雪冰城、库迪贴身肉搏!
瑞幸向下,加盟单店投入70万
库迪反攻,雪王贴身肉搏,下沉市场混战
咖啡决战在几年后?
抛开两个玩家之争,更长远来看,咖啡赛道的竞争对手远不止于同类玩家。“咖啡未来最大的竞争对手是奶茶”,朱拥华如此预判。
转自:https://mp.weixin.qq.com/s/4O4uL5cUWV16ADhvNTlDTQ
北京快递现状与恢复展望
1、目前网点的阳性情况,包括目前的单量的情况?
我们站点员工 31 人,已经阳完 27个人,目前已经逐步阳完,恢复正常工作了。目前的派件效率是不太好,也就是达到正常的 70% 左右,毕竟北京疫情延误的很厉害。即使这两天身体有所恢复了,但是各项技能还不行,也就是平时的 70% 到 80% 的状态。
按我们最早一批出现身体状态的阳性来看,差不多有半个月了,身体已经完全恢复了正常。估摸着再有个一个礼拜左右,剩下这些人应该能完全恢复,没观察到有什么后遗症之类的。
单量正常的是 11000 单,这几天的单量差不多是在 5000 票左右,因为我们之前关停了几天,刚刚打开,现在是在一半,预计 3- 5 天完全恢复正常。
全国其他地方快递发不进来,北京的需求量现在特别大,因为我们同行快递现在是正常货量的 3 倍,中通因为占主体货量比较大,我们一关停之后,其他快递的货量暴涨,已经涨到 3 倍了。
2、这一波北京的快递受影响各家大概是什么样的情况?包括恢复的节奏。
这波疫情对各大快递影响都挺大的。我们应该是阳的比较早的站点,所以现在 90% 以上的人已经正常恢复上岗了,但是我们周边的网点包括中通在内,大部分还处在半停状态,可能 40% 到 50% 的上岗率,尤其是以京东为主。京东感染特别厉害,京东现在站点基本上还都处在关停状态。通达的同行这波影响都挺大的。圆通据我了解是有一也是一半人在岗,另外一半人也是暂停状态,他们的货量积压挺厉害的。因为圆通和我们不一样,中通可以申请部分报停或者完全报停,但是圆通总部政策不一样,它是不让报停,所以他们的货一直是在压着的状态,压货量挺大。韵达因为北京韵达今年一直有情况,所以他们货量不是太大。韵达没什么太大影响,本身它货量体系小,所以人员有几个上班不上班,没什么太大影响。
申通今年双 11 期间,申通数据转运中心本身出现问题,所以导致他们一直没货。可能相对来说他的员工也是安全的,相对来申通可能员工感染阳性比较少。我昨天给周边的申通打过电话,他们十几个人的站点也就有一两个感染的状态,没什么太大影响。
顺丰北京他们人员比较充足,目前没什么太大影响,他们的派件还有揽收。顺丰的人员的缺口小一点,因为顺丰相对来说取件收费高,我们同一个区域派送我们只安排一个人,他们说是安排三个人。他俩人同时阳,还能剩一个人派送,但是我们一个人阳,那这个片区基本已经停滞。
估计过半个月左右北京快递行业应该能恢复正常。
3、在疫情的影响之下,总部或者我们北京的省区有没有对我们网点做一些补贴?从 12 月 16 号开始是每单的进港件,现在都补贴到了 3 毛,直接涨了 3 毛钱派费。不是补贴到快递员,是补到我们的房租成本里边,因为差不多没得有将近一个多月没有上班了,但是这一月我们的房租还有后勤的工资是照开的,肯定不可能再补给快递员了,如果补给快递员干点,肯定是谁也承受不住。补贴需要看补贴多长时间,这一段时间的补贴损失,它至少得补3个月,如果按照以往的规则来算,它最多也就涨半个月,则无法弥补最近的损失。
4、对于明年预期?
市场份额方面因为竞争格局都已经比较稳定,没有观察到各家份额有太大流失。
正常来看,明年肯定快递行业肯定是挣钱的。今年我们亏本就是亏在关停状态上了, 6 月份关停了差不多一个月,十一二月份差不多又关停了一个月,这两个月我们亏损特别厉害。12 月份的这波疫情,我也准备已经要准备上车购买大型货车和一套分拣设备,因为就这疫情原因导致搁浅了。
总结:
从我们小区的感受来说,顺丰基本没太受到影响,京东、三通一达前两周基本停滞,中通停滞时间最长。不过这两天都已经开始逐渐恢复。
其他方面数据,北京的发热搜索指数高峰已经过去,地铁客流量这两天也已经开始回升。估计再过半个月左右北京地区应该能恢复正常,冲击为一个月左右。
预计快递行业明年会有明显回升。
转自:https://mp.weixin.qq.com/s/a5YL2SrJme3SANkHPBwRww
迪玛利亚:他们并不知道赫拉克勒斯
作者:迪玛利亚
其实他的主业并不是挖木炭,他曾经试过把我家的门面变成一家小卖部。父亲引进了大桶的漂白剂、氯水、肥皂还有许多的清洁剂,然后他会把这些分进一个个瓶子里,最后通过小卖部再贩卖出去。如果你生活在我们的小镇上的话,你买一瓶柠檬清洁剂是不会去正规的商店的,那太贵了。你可以来到我们家的小店里,我妈妈会卖给你一瓶同样的清洁剂,价格也会合理得多。
瞧瞧别人家的 API 接口,那叫一个优雅!
前言
在实际工作中,我们需要经常跟第三方平台打交道,可能会对接第三方平台API接口,或者提供API接口给第三方平台调用。
那么问题来了,如何设计一个优雅的API接口,能够满足:安全性、可重复调用、稳定性、好定位问题等多方面需求?
今天跟大家一起聊聊设计API接口时,需要注意的一些地方,希望对你会有所帮助。
1. 签名
为了防止API接口中的数据被篡改,很多时候我们需要对API接口做签名
。
接口请求方将请求参数
+ 时间戳
+ 密钥
拼接成一个字符串,然后通过md5
等hash算法,生成一个前面sign。
然后在请求参数或者请求头中,增加sign参数,传递给API接口。
API接口的网关服务,获取到该sign值,然后用相同的请求参数 + 时间戳 + 密钥拼接成一个字符串,用相同的m5算法生成另外一个sign,对比两个sign值是否相等。
如果两个sign相等,则认为是有效请求,API接口的网关服务会将给请求转发给相应的业务系统。
如果两个sign不相等,则API接口的网关服务会直接返回签名错误。
问题来了:签名中为什么要加时间戳?
答:为了安全性考虑,防止同一次请求被反复利用,增加了密钥没破解的可能性,我们必须要对每次请求都设置一个合理的过期时间,比如:15分钟。
这样一次请求,在15分钟之内是有效的,超过15分钟,API接口的网关服务会返回超过有效期的异常提示。
目前生成签名中的密钥有两种形式:
一种是双方约定一个固定值privateKey。
另一种是API接口提供方给出AK/SK两个值,双方约定用SK作为签名中的密钥。AK接口调用方作为header中的accessKey传递给API接口提供方,这样API接口提供方可以根据AK获取到SK,而生成新的sgin。
2. 加密
有些时候,我们的API接口直接传递的非常重要的数据,比如:用户的银行卡号、转账金额、用户身份证等,如果将这些参数,直接明文,暴露到公网上是非常危险的事情。
由此,我们需要对数据进行加密
。
目前使用比较多的是用BASE64
加解密。
我们可以将所有的数据,安装一定的规律拼接成一个大的字符串,然后在加一个密钥
,拼接到一起。
然后使用JDK1.8之后的Base64工具类处理,效果如下:
【加密前的数据】www.baidu.com
【加密后的数据】d3d3LmJhaWR1LmNvbQ==
为了安全性,使用Base64可以加密多次。
API接口的调用方在传递参数时,body中只有一个参数data,它就是base64之后的加密数据。
API接口的网关服务,在接收到data数据后,根据双方事先预定的密钥、加密算法、加密次数等,进行解密,并且反序列化出参数数据。
3. ip白名单
为了进一步加强API接口的安全性,防止接口的签名或者加密被破解了,攻击者可以在自己的服务器上请求该接口。
需求限制请求ip
,增加ip白名单
。
只有在白名单中的ip地址,才能成功请求API接口,否则直接返回无访问权限。
ip白名单也可以加在API网关服务上。
但也要防止公司的内部应用服务器被攻破,这种情况也可以从内部服务器上发起API接口的请求。
这时候就需要增加web防火墙了,比如:ModSecurity等。
4. 限流
如果你的API接口被第三方平台调用了,这就意味着着,调用频率是没法控制的。
第三方平台调用你的API接口时,如果并发量一下子太高,可能会导致你的API服务不可用,接口直接挂掉。
由此,必须要对API接口做限流
。
限流方法有三种:
-
对请求ip做限流:比如同一个ip,在一分钟内,对 API接口总的请求次数
,不能超过10000次。 -
对请求接口做限流:比如同一个ip,在一分钟内,对 指定的API接口
,请求次数不能超过2000次。 -
对请求用户做限流:比如同一个 AK/SK用户
,在一分钟内,对API接口总的请求次数,不能超过10000次。
我们在实际工作中,可以通过nginx
,redis
或者gateway
实现限流的功能。
5. 参数校验
我们需要对API接口做参数校验
,比如:校验必填字段是否为空,校验字段类型,校验字段长度,校验枚举值等等。
这样做可以拦截一些无效的请求。
比如在新增数据时,字段长度超过了数据字段的最大长度,数据库会直接报错。
但这种异常的请求,我们完全可以在API接口的前期进行识别,没有必要走到数据库保存数据那一步,浪费系统资源。
有些金额字段,本来是正数,但如果用户传入了负数,万一接口没做校验,可能会导致一些没必要的损失。
还有些状态字段,如果不做校验,用户如果传入了系统中不存在的枚举值,就会导致保存的数据异常。
由此可见,做参数校验是非常有必要的。
在Java中校验数据使用最多的是hiberate
的Validator
框架,它里面包含了@Null、@NotEmpty、@Size、@Max、@Min等注解。
用它们校验数据非常方便。
当然有些日期字段和枚举字段,可能需要通过自定义注解的方式实现参数校验。
6. 统一返回值
我之前调用过别人的API接口,正常返回数据是一种json格式,比如:
{
"code":0,
"message":null,
"data":[{"id":123,"name":"abc"}]
},
签名错误返回的json格式:
{
"code":1001,
"message":"签名错误",
"data":null
}
没有数据权限返回的json格式:
{
"rt":10,
"errorMgt":"没有权限",
"result":null
}
这种是比较坑的做法,返回值中有多种不同格式的返回数据,这样会导致对接方很难理解。
出现这种情况,可能是API网关定义了一直返回值结构,业务系统定义了另外一种返回值结构。如果是网关异常,则返回网关定义的返回值结构,如果是业务系统异常,则返回业务系统的返回值结构。
但这样会导致API接口出现不同的异常时,返回不同的返回值结构,非常不利于接口的维护。
其实这个问题我们可以在设计API网关
时解决。
业务系统在出现异常时,抛出业务异常的RuntimeException,其中有个message字段定义异常信息。
所有的API接口都必须经过API网关,API网关捕获该业务异常,然后转换成统一的异常结构返回,这样能统一返回值结构。
7. 统一封装异常
我们的API接口需要对异常
进行统一处理。
不知道你有没有遇到过这种场景:有时候在API接口中,需要访问数据库,但表不存在,或者sql语句异常,就会直接把sql信息在API接口中直接返回。
返回值中包含了异常堆栈信息
、数据库信息
、错误代码和行数
等信息。
如果直接把这些内容暴露给第三方平台,是很危险的事情。
有些不法分子,利用接口返回值中的这些信息,有可能会进行sql注入或者直接脱库,而对我们系统造成一定的损失。
因此非常有必要对API接口中的异常做统一处理,把异常转换成这样:
{
"code":500,
"message":"服务器内部错误",
"data":null
}
返回码code
是500
,返回信息message
是服务器内部异常
。
这样第三方平台就知道是API接口出现了内部问题,但不知道具体原因,他们可以找我们排查问题。
我们可以在内部的日志文件中,把堆栈信息、数据库信息、错误代码行数等信息,打印出来。
我们可以在gateway
中对异常进行拦截,做统一封装,然后给第三方平台的是处理后没有敏感信息的错误信息。
8. 请求日志
在第三方平台请求你的API接口时,接口的请求日志非常重要,通过它可以快速的分析和定位问题。
我们需要把API接口的请求url、请求参数、请求头、请求方式、响应数据和响应时间等,记录到日志文件中。
最好有traceId
,可以通过它串联整个请求的日志,过滤多余的日志。
当然有些时候,请求日志不光是你们公司开发人员需要查看,第三方平台的用户也需要能查看接口的请求日志。
这时就需要把日志落地到数据库,比如:mongodb
或者elastic search
,然后做一个UI页面,给第三方平台的用户开通查看权限。这样他们就能在外网查看请求日志了,他们自己也能定位一部分问题。
9. 幂等设计
第三方平台极有可能在极短的时间内,请求我们接口多次,比如:在1秒内请求两次。有可能是他们业务系统有bug,或者在做接口调用失败重试,因此我们的API接口需要做幂等设计
。
也就是说要支持在极短的时间内,第三方平台用相同的参数请求API接口多次,第一次请求数据库会新增数据,但第二次请求以后就不会新增数据,但也会返回成功。
这样做的目的是不会产生错误数据。
我们在日常工作中,可以通过在数据库
中增加唯一索引
,或者在redis
保存requestId
和请求参来保证接口幂等性。
10. 限制记录条数
对于对我提供的批量接口,一定要限制请求的记录条数
。
如果请求的数据太多,很容易造成API接口超时
等问题,让API接口变得不稳定。
通常情况下,建议一次请求中的参数,最多支持传入500条记录。
如果用户传入多余500条记录,则接口直接给出提示。
建议这个参数做成可配置的,并且要事先跟第三方平台协商好,避免上线后产生不必要的问题。
11. 压测
上线前我们务必要对API接口做一下压力测试
,知道各个接口的qps
情况。
以便于我们能够更好的预估,需要部署多少服务器节点,对于API接口的稳定性至关重要。
之前虽说对API接口做了限流,但是实际上API接口是否能够达到限制的阀值,这是一个问号,如果不做压力测试,是有很大风险的。
比如:你API接口限流1秒只允许50次请求,但实际API接口只能处理30次请求,这样你的API接口也会处理不过来。
我们在工作中可以用jmeter
或者apache benc
对API接口做压力测试。
12. 异步处理
一般的API接口的逻辑都是同步处理的,请求完之后立刻返回结果。
但有时候,我们的API接口里面的业务逻辑非常复杂,特别是有些批量接口,如果同步处理业务,耗时会非常长。
这种情况下,为了提升API接口的性能,我们可以改成异步处理
。
在API接口中可以发送一条mq消息
,然后直接返回成功。之后,有个专门的mq消费者
去异步消费该消息,做业务逻辑处理。
直接异步处理的接口,第三方平台有两种方式获取到。
第一种方式是:我们回调
第三方平台的接口,告知他们API接口的处理结果,很多支付接口就是这么玩的。
第二种方式是:第三方平台通过轮询
调用我们另外一个查询状态的API接口,每隔一段时间查询一次状态,传入的参数是之前的那个API接口中的id集合。
13. 数据脱敏
有时候第三方平台调用我们API接口时,获取的数据中有一部分是敏感数据,比如:用户手机号、银行卡号等等。
这样信息如果通过API接口直接保留到外网,是非常不安全的,很容易造成用户隐私数据泄露的问题。
这就需要对部分数据做数据脱敏
了。
我们可以在返回的数据中,部分内容用星号
代替。
已用户手机号为例:182****887
。
这样即使数据被泄露了,也只泄露了一部分,不法分子拿到这份数据也没啥用。
14. 完整的接口文档
说实话,一份完整的API接口文档,在双方做接口对接时,可以减少很多沟通成本,让对方少走很多弯路。
接口文档中需要包含如下信息:
-
接口地址 -
请求方式,比如:post或get -
请求参数和字段介绍 -
返回值和字段介绍 -
返回码和错误信息 -
加密或签名示例 -
完整的请求demo -
额外的说明,比如:开通ip白名单。
接口文档中最好能够统一接口和字段名称的命名风格,比如都用驼峰标识
命名。
接口地址中可以加一个版本号v1,比如:v1/query/getCategory,这样以后接口有很大的变动,可以非常方便升级版本。
统一字段的类型和长度,比如:id字段用Long类型,长度规定20。status字段用int类型,长度固定2等。
统一时间格式字段,比如:time用String类型,格式为:yyyy-MM-dd HH:mm:ss。
接口文档中写明AK/SK和域名,找某某单独提供等。
– EOF –
转自:https://mp.weixin.qq.com/s/vt78yXSUhSFGkR_fBKWuaw