技术开发阅读笔记

发布于 2022-09-23 23:44:46 字数 8467 浏览 160 评论 0

Metrics 指标设计之 RED 大法

  • Rate 速率
  • Errors 错误
  • Duration 持续时间

Metrics指标设计之USE大法

  • Utilization 利用率
  • Saturation 饱和状态
  • Errors 事件错误

OpenResty系统调优

  • CPU affinity 亲和性配置
  • NGINX 配置优化
  • Linux sysclt 设置
  • Intel Quickassist

NGINX 指令配置

  • keepalive_timeout, keepalive_requests
  • sendfile on - copy fd at kernel level
  • tcp_nopush, tcp_nodelay
  • listen backlog reuserport

Linux sysclt 设置

  • Memory
  • Size of processor queue
  • Maximum TCP buffer size
  • Disable TCP timestamps

OpenResty / Lua 高级编程技巧,OpenResty/Lua 70+ Advanced Programming Skills and Optimization tips

Debug

逻辑运算符 and、or 和 not 是经常隐藏 bug 的地方,比如:

if (type(t) == 'table' and t.x == 'abc')

就算 t 不是 table 类型,那么 lua 的短路求值也不会对 t 进行求值,所以不会引发运行时错误

用 xpcall debug

function errorFunc() 
       local a = 20
       print(a[10])
end
function errorHandle() 
       print(debug.traceback())
end
if xpcall(errorFunc, errorHandle) then
       print("This is OK.")
else
       print("This is error.")
end

ngx.now() :获取当前时间,包括毫秒数
os.clock():返回CPU时间的描述,通常用于计算一段代 码的执行效率

os.data 日期对象函数:print(os.date("%Y-%m-%d")) --输出2012-04-05

以下的 debug 方式我们一般不用

  1. 直接抛出错误:error(抛出个 error!)
  2. assert(io.read("*number"), "invalid input")
  3. Lua提供了错误处理函数 pcall:r, msg = pcall(foo)
  4. 还可以用 xpcall

一般情况下我们是直接面对 error log 来开发 tailf /home/openresty/nginx/logs/error.log

Safety

URL 参数转义

urlencode : ngx.escape_uri
urldecode : ngx.unescape_uri

local act = ngx.var.arg_act and ngx.unescape_uri(ngx.var.arg_act) or ngx.var.act

过滤/指定 remote_addr

ngx.var.remote_addr == "132.5.72.3"

获取用户 ip

local clienIP = ngx.req.get_headers()["x-real-ip"] 
if clienIP == nil then
    clienIP = ngx.req.get_headers()["x_forworded_for"] 
end
if clienIP == nil then
    clienIP = ngx.var.remote_addr
end

Sql Injection

local name = ngx.unescape_uri(ngx.var.arg_name) 
local quoted_name = ngx.quote_sql_str(name)
local sql = "select * from users where name = " .. quoted_name

htmlspecialchars 的实现

function htmlspecialchars(str)
     local rs = str or nil
     if rs and type(rs) == 'string' then
          rs = string.gsub(rs, '&', '&') 
          rs = string.gsub(rs, '"', '"') 
          rs = string.gsub(rs, "'", ''') 
          rs = string.gsub(rs, '<', '<')
          rs = string.gsub(rs, '>', '>') 
          end
      return rs 
end

过滤特殊字符

local illegal = {
["-"] = true, ["_"] = false, ["."] = false, ["!"] = true, [":"] = true, ["@"] = true,
["&"] = true, ["~"] = true, ["*"] = true, ["'"] = true, ['"'] = true, ["="] = false,
["("] = true, [")"] = true, ["["] = true, ["]"] = true, ["{"] = true, ["}"] = true,
["+"] = true, ["$"] = false, [","] = false, [";"] = true, ["?"] = true, ["%"] = true,
["^"] = true, ["/"] = true, ["|"] = true, ["#"] = true, ['-'] = true, ["_"] = false, ["。"] = true, 
['!'] = true, [':'] = true, ['@'] = true, ['&'] = true, ['~'] = true, ['*'] = true, ['‘'] = true, ['’'] = true, 
['“'] = true, ['”'] = true, ['('] = true, [')'] = true, ['['] = true, [']'] = true,
 ['{'] = true, ['}'] = true, ['+'] = true, ['¥'] = true, [','] = true, [';'] = true, ['?'] = true, 
['%'] = true, ['^'] = true, ['/'] = true, ['......'] = true,
}
local filter = function(c)
      if illegal[c] then 
            return ' '
      end
      return c 
end
cnt = string.gsub(cnt, '([^a-zA-Z0-9])', filter)

Magics Convert

function escapeMagic(s)
      local rs
      if type(s) == 'string' then
            rs = (s:gsub(‘[%-%.%+%[%]%(%)%$%^%%%?%*]',
                  '%%%1'):gsub('%z', '%%z')) 
      end
      return rs 
end

过滤 v 中的疑似网址特征

local spos = find(v, 'www') or find(v, '%.') or find(v, '。') or find(v, '点')
local substring = '' if spos then
      substring = string.sub(s, spos, epos) 
      substring = g.escapeMagic(substring) 
      v = string.gsub(s, substring, '')
end

Build Queries

bind['so_refer_key'] = g.trim(vinfo['so_refer_key']) bind['request_from'] = 'info_relate'
bind['wt'] = 'json'
bind['qt'] = 'standard'
bind['56_version'] = ngx.var.arg_rvc bind['so_refer_key'] = ngx.var.arg_so_refer_key or ''

local param = neturl.buildQuery(bind)
local host = 'related_video.solr.56.com' -- local port = '49715'
local uri = '/solrRelateVideo/select?' .. param 
if ngx.var.arg_dg == 'ml' then
      print(uri) 
end

xssfilter

-- Filter the XSS attack
local xssfilter = require("lib.xssfilter")
local xss_filter = xssfilter.new()
data['title'] = g.htmlentities(xss_filter:filter(data['title']))

Sandbox

-- 使用 closure 创建 sandbox (安全运行环境),比如为 io.open 提供权限控制的功能
do
local oldOpen = io.open
local checkAccess = function (file, mode)
      -- check if current user with 'mode' can access the 'file' end
io.open = function (file, mode)
      if checkAccess(file, mode) then
            return oldOpen(file, mode) 
      else
            return nil, "access, denied" end
      end 
end

Metatable

t = {}
print(getmetatable(t))
-- 输出为 nil,table 创建时默认没有元表
-- 任何 table 都可以作为任何值的元表,在Lua代码中, 只能设置table的元表

Table Sorting

t = {5,1,3,6,3,2}
t2 = table.sort(t, function(a1, a2) return (a1 > a2) end) 
for i, v in ipairs(t) do print(v)  end

在线代码运行环境

labstack

repl.it

glot.io

缓存雪崩、缓存击穿、缓存穿透

缓存雪崩

大量的 KEY 过期时间过于集中,导致瞬时很多缓存失效,由此可能导致数据库压力陡然升高。
解决方案:将失效时间随机打乱,如在系统启动预热时设定一定程度上离散的过期时间。

缓存击穿

缓存中某一个 KEY 过期失效,如果此时有大量请求过来无法命中缓存的 KEY,缓存层像被凿开了一个口子一样流入大量数据库查询请求
解决方案:双重校验方式从数据库中读取数据到缓存。双重校验:第一层查询缓存失败后,进入临界区,保证同时只有一个请求线程读取数据库,进入临界区后再次尝试缓存,仍然没有命中则查询数据库。

缓存穿透

外部请求不断查询一个系统中不存在的数据,服务无法命中缓存转而每次尝试从数据库中查询。
解决方案:对查询结果为空 key 设置值为 null 的缓存,牺牲缓存空间换响应时间。把所有非法的key映射到一个bitmap中,通过bitmap拦截。《布隆过滤器》原理

JAVA 基本类型 int 和 long 的理解

long 可以用来计算光在一定时间内走过的距离。

光在一秒内大约传播 30 万千米。如果编写一个程序来跟踪光走过的距离,那么7秒后 int 类型就超出范围类,而 long 类型能够计算大约 975 年。不相信吗?可以看看这个gist中的计算。

Light Distance Calculation: 32-bit vs. 64-bit

Some Facts:

  1. Maximum Positive Signed 32-bit Integer: (2^31) - 1 = 2,147,483,647
  2. Maximum Positive Signed 64-bit Integer: (2^63) - 1 = 9,223,372,036,854,775,807
  3. Speed of Light: 299,792,458 m/s

If an integer were tracking meters in real time:

  1. 32-bit Calculation
    In seconds: 2,147,483,638 m / 299,792,458 m/s = 7.16323436662 s
  2. 64-bit Calculation
    In seconds: 9,223,372,036,854,775,807 m / 299,792,458 m/s = 30,765,857,481.5 s
    In minutes: 30,765,857,481.5 s / 60 s/min = 512,764,291.358 mins
    In hours: 512,764,291.358 mins / 60 mins/hour = 8,546,071.52264 hours
    In days: 8,546,071.52264 hours / 24 hours/day = 356,086.313443 days
    In years: 356,086.313443 days / 365.25 days/year = 974.911193547 years

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

原来是傀儡

暂无简介

0 文章
0 评论
26 人气
更多

推荐作者

娇女薄笑

文章 0 评论 0

biaggi

文章 0 评论 0

xiaolangfanhua

文章 0 评论 0

rivulet

文章 0 评论 0

我三岁

文章 0 评论 0

薆情海

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文