聊聊短地址服务的实现

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 前言 一个长URL地址,形如 “https://www.google.com.hk/search?q=%E7%9F%AD%E5%9C%B0%E5%9D%80%E6%9C%8D%E5%8A%A1&oq=%E7%9F%AD%E5%9C%B0%E5%9D%80%E6%9C%8D%E5%8A%A1&aqs=chrome..69i57j69i61.4824j1j7&sourceid=chrome&ie=UTF-8" , 由于不可避免的带有PATH、各种参数和追踪标识,这导致URL往往很长。当你要把这个URL发送给其它人时,可能会变得很不方便。比如短信/微博有字数限制。或者对方将链接粘贴到浏览器时,容易漏掉部分数据。 因此短链接服务就显得非常重要。(短链接还可以使的生成的二维码色块更大,提高识别速度) 国内常见的短地址服务有新浪 百度 那么他们是怎么实现的呢? 建议先阅读参考资料1 2. 实现&原理 2.1 实现 萌叔受到参考资料1的启发也实现了一版。 vearne/tinyurl 代码及使用步骤见README 你也可以 在线尝试 2.2 生成短地址 1) 将长地址与一个整数建立映射(一对多) 这里整数使用int64,保存映射关系。笔者为了简单使用是MySQL数据库,如果为了更好的并发存储,还可以NoSQL数据库或者数据分分库分表。 "https://github.com/vearne/tinyurl" -> 10363 这里主键id就是整数值 长地址存储在url字段中 +-------+---------------------------------+---------------------+ | id | url | created_at | +-------+---------------------------------+---------------------+ | 10000 | http://vearne.cc/archives/39217 | 2019-11-28 14:02:56 | +-------+---------------------------------+---------------------+ 提示 这里不能用哈希的原因是,哈希后的值如果太短则容易出现碰撞,如果太长则压缩的效率太低,没有意义。 2)base62编码 整数如果直接按字符串传输,长度还是太长。可以对整数进行base62编码 之所以是62,其实是 26个小写英文字母[a-z], 26个大写英文字母[A-Z], 以及阿拉伯数字[0-9]。有意的避开特殊符号和不可见字符。 3) 拼接上域名 就得形如, 短链接地址: http://st.vearne.cc/2h9 2.3 访问短地址 访问短地址得到长地址的过程与短地址的生成过程刚好相反 1)base62解码 base62解码得到整数 ...

November 29, 2019 · 1 min

openresty写入用户唯一标识(cookie)

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 前言 最近打算在blog里面,增加个性化推荐,以增加访问量。这一切的前提是,我要能够标识出每个用户,以及记录用户的浏览记录。这里笔者采用openresty在cookie中写入用户标识,然后在日志中记录下用户的浏览记录,供后续分析使用 2. 详解 1)nginx 配置 upstream blog { server 127.0.0.1:8080; } server { listen 80; #端口 server_name blog.vearne.cc; location ^~ /archives/ { rewrite_by_lua_file 'conf/lua/set-ck.lua'; proxy_pass http://blog; } location /{ proxy_pass http://blog; } } 2)Lua脚本 set-ck.lua 如果用户没有对应的cookie "UT_ID", 则注入cookie的同时,返回一个302临时跳转, 客户再次访问时,由于已经拥有响应cookie,所以可以直接访问后端服务 local cookie_name = "cookie_UT_ID" local request_uri = ngx.var.request_uri if ngx.var[cookie_name] == nil then local uuid = io.open("/proc/sys/kernel/random/uuid", "r"):read() local mycookie = string.format("UT_ID=%s; Expires=%s", uuid, ngx.cookie_time(ngx.time() + 86400 * 1000)) ngx.header["Set-Cookie"] = mycookie ngx.header["Location"] = request_uri ngx.exit(302) end 这里另一个有趣的地方是,可以直接通过读取文件 "/proc/sys/kernel/random/uuid" 来生成一个uuid ...

November 5, 2018 · 1 min

聊聊HttpCode 301和302 重定向

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 前言 HTTP状态码 除了最常见的200,201,其实302应该是我们用的最多的,尤其是在Oauth实现中 简单说明 301 Moved Permanently 描述 状态码301表示永久重定向 场景 网址永久变更 302 Moved Temporarily 描述 状态码302表示临时重定向 场景 网址(资源)临时变更,特别是在Oauth、单点登录等过程中,被大量使用 过程说明 下面是我用python实现的http server的简单例子 redirect.py import time import tornado.ioloop import tornado.web class PermanentlyHandler(tornado.web.RequestHandler): def get(self): print '--301 Permanently--' self.redirect('http://vearne.cc/archives/365', permanent=True) class TemporarilyHandler(tornado.web.RequestHandler): def get(self): print '--302 Temporarily--' self.redirect('http://vearne.cc/archives/365', permanent=False) def make_app(): return tornado.web.Application([ (r"/abc", PermanentlyHandler), (r"/def", TemporarilyHandler), ]) if __name__ == "__main__": app = make_app() app.listen(8888) tornado.ioloop.IOLoop.current().start() 可以直接使用浏览器模拟请求 让我们来观察一下301和302请求的实际返回 ...

March 2, 2018 · 2 min