不同网络拓扑下如何正确获取客户端ip?

先说结论:

  • 说明:一切抛开网络拓扑提准确获取用户ip的通用方案都是耍流氓。
  • 根据网络拓扑当服务器架构中的设备IP加入可信IP列表,成本:持续维护可信IP区、与拓扑相关、增加防火墙WAF调整可信IP
  • 剔除可信IP列表
  • 从XFF头部倒序获取首个非可信IP作为客户端真实IP,防伪造XFF、防代理、保正常请求
  • Laravel/Nginx-realip均按上述逻辑来处理的

网络拓扑模型


MySQL InnoDB在线调整表结构(online DDL)-新增字段篇

线上服务的表结构调整是业务需求扩展和系统设计拓宽的常见方式,但对线上服务而言,线上库表调整可能对线上服务产生影响。
本文以MySQL 5.6.16-log为例,结合InnoDB引擎特性,给出综合分析,几个核心问题:

  1. 线上库修改表结构操作是否会导致锁表、锁行?
  2. 线上改表结构可用的方案有哪些?各自成本和适用场景?
  3. 5.6+ InnoDB引擎的online DDL特性性能表现如何?

Linux内存之Slab

Linux内存管理模式,页式管理适合于大块内存的情形,而对于内核对象级别的较小内存情形下,不足以占用1个页。

在linux内核中会有许多小对象,这些对象构造销毁十分频繁,比如i-node,dentry。这么这些对象如果每次构建的时候就向内存要一个页,而其实际大小可能只有几个字节,这样就非常浪费,为了解决这个问题就引入了一种新的机制来处理在同一页框中如何分配小存储器区。这就是我们要讨论的slab层。在讲述slab前,我想先铺垫一下有关内存页的概念,我们都知道在linux中内存都是以页为单位来进行管理的(通常为4KB),当内核需要内存就调用如:kmem_getpages这样的接口(底层调用__alloc_pages())。那么内核是如何管理页的分配的,这里linux使用了伙伴算法。slab也是向内核申请一个个页,然后再对这些页框做管理来达到分配小存储区的目的的。

深入理解Golang中的interface(一)

原文地址:https://medium.com/golangspec/interfaces-in-go-part-i-4ae53a97479c

要点:

  • 接口是系列方法的集合
  • 单个类型可以实现多个方法
  • 同一个接口可以被多种类型实现
  • 接口声明可内嵌其他接口,导入内嵌接口的所有方法(可导出方法+不可导出方法),多层内嵌接口也将全部被导入到接口声明中
  • 禁止接口的循环内嵌
  • 接口内方法名必须唯一:自定义方法和内嵌接口包含方法,名称必须唯一
  • 接口变量可以保存所有实现了此接口的所有类型的值:抽象的理论实现
  • 静态类型VS动态类型:接口类型的变量可以被实现了其接口的类型间相互赋值,动态类型
  • 接口类型变量:动态类型、动态值,只有二者均为零值nil时此接口类型的变量才为nil
  • 空接口:可以承载任何类型的变量,也可以说任何类型都实现(满足)了空接口
  • 接口实现:类型定义了包含某接口声明的所有方法(方法名+签名一致)
  • 接口类型值只能访问接口自身定义的方法,原类型的其他变量无法访问:行为的抽象,联想对比Java中子类赋值给父类时多态特性

Redis事务及CAS(Check-And-Set)机制

Redis事务

在web/activity中见过事务机制保证发券环节对券码存量校验,这是典型的并发、读写操作的实例。

Redis的事务机制Transaction通过四个命令来完成:MULTI, EXEC, DISCARD and WATCH,建议精读链接文章对Redis事务机制有详细介绍。

Redis事务机制特性

  • 事务(transaction)的定义从multi开始,到exec结束。
  • 同一个事务内的多个命令,具有原子性,不会被打断

    It can never happen that a request issued by another client is served in the middle of the execution of a Redis transaction. This guarantees that the commands are executed as a single isolated operation.

PHP中非空判断、三目、类型转换的坑点

文章索引:

  • isset()empty()is_null()的区别
  • == 和 ===区别
  • 类型转换后到底哪些是false?
  • 三目运算符区别:? : 、?:和??
  • 访问数组中不存在索引时,会怎么样?

isset()empty()is_null()的区别

  • isset()判断变量是否已设置(set)且非null,isset()官方文档

    • 变量被unset()后,则isset()返回false
    • 变量值为null,则issset()返回false
    • isset()函数支持多参数,如isset($foo, $bar)
    • isset()判断数组是否包含特定索引值,注意数组值为null的情形