技术总结

ShortURL系统实现

在知乎上看了一个很有启发的回答,因此实际动手来实现短URL生成系统。贴上链接: 知乎 - 短URL系统是如何设计的。其中提到了,要实现短URL生成系统要解决的问题有:

  • 如何优雅的实现?
  • 怎么基本实现长对短、一对一?
  • 如何实现分布式,高并发,高可用?
  • 储存选用?

基本原理 #

数据库自增ID转换62进制

  1. 使用自增ID不会产生重复的短链接。
  2. 为了解决自增ID超长和不便记忆,对ID进行62进制编码。所谓62进制就是0-9,a-z,A-Z。

简单计算下:

62 ^ 4 = 14,776,336
62 ^ 5 = 916,132,832
62 ^ 6 = 56,800,235,584 // 已经足够使用了

总体结构及处理流程 #

服务结构

长链接处理流程 #

  1. 获取参数,调用shortURL服务
  2. 尝试从缓存中获取,如果命中,则读取短链接(重置过期时间)。跳转第4步
  3. 将长链接存储到Mysql数据库,根据ID进行base62编码,组装Domain+Encoded字符串并更新数据库
  4. 返回生成的短链接

短链接处理流程 #

  1. 解析短链接为ID
  2. 查询ID对应的长链接
  3. 以301方式跳转到长链接

长链接与短链接的对应关系 #

一对多,一个长链接可能对应多个短链接。数据表存储结构如下:

+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| id        | int(64)      | NO   | PRI | NULL    | auto_increment |
| long_url  | varchar(100) | NO   |     | NULL    |                |
| short_url | varchar(40)  | YES  |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+

分布式和高并发设计 #

###注:这部分未实现。我的思路如下:

...

Golang服务端技术笔记

总结使用Golang开发服务端时,使用的基础的工具和部署方式。用于思考不足并优化,提升编码效率。 总体上采用MVCS的软件模式,如下图:

MVCS模式

从图中可以看出,MVCS是从MVC进化而来,相比于MVC,增加了Service层。把业务逻辑从Controller层中抽离出来,这样做的好处在于,项目日益庞大之后,将某些功能独立出来。

Golang工具 #

“gvt” 依赖管理工具 “httprouter” 路由及中间件配置 “schema” 解析请求参数到结构体 “beego/validation” 结构体校验工具 “github.com/go-redis/redis” redis操作库 “github.com/go-sql-driver/mysql” Mysql Driver

文件结构 #

--Golang Project
    |-sh            # shell脚本,包括数据库脚本
    |-config        # 配置文件
    |-logs          # 日志文件
    |-vendor        # 项目源码及依赖
    |  |-github.com #
    |  |-mainfest   # gvt 依赖管理文件
    |  |-app
    |     |-utils
    |     |-controllers
    |     |-models
    |     |-route
    |     |-services
    |-Dockerfile    # docker构建镜像配置文件
    |-docker-compose.yml # docker-compose.yml文件
    `-entry.go      # web服务入口文件

部署方式 #

采用docker来部署应用。分别编写Dockerfile和docker-composer.yml文件,实例如下:

...

docker-compose上手

docker compose 用于快速在集群中部署分布式应用。按我的理解也可以用于简化部署单个应用。譬如我要使用dock er启动一个nginx服务,需要做端口映射,挂载数据文件,指定镜像…等等,这种情况下,可以将启动容器的命令整合到docker-compose.yml文件中,可以在多个服务器上运行,瞬间就完成了nginx的安装及配置,再也不用去编译,解决环境依赖了,这种感觉实在是太爽了!!!

安装 #

  1. 使用pip pip install docker-compose
  2. 从官方Github Release下载二进制包文件
  3. 其他方法略去

使用场景 #

在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。

实战场景 #

需要部署的项目,只有两个docker容器,一个server,一个db。一般的部署方式是,分别启动两个容器,容器间通过互联的方式通信:

sudo docker run --rm -p 5433:5432 --name postgres -e POSTGRES_PASSWORD=minepwd -e POSTGRES_USER=mineusr -d postgres

sudo docker run --rm -p 9091:9091 --link postgres:postgres --name mineserver -d me/mineserver

这两条命令还是有挺麻烦的,如果记不住,当然可以用shell脚本来运行,可以如果其中某一个服务无法如期运行。。。就很监介了。这时候就可以引入docker-compose了。

编写docker-compose.yml来部署项目 #

version: "2" # 指定docker-compose版本
services:    # 项目依赖的服务
  postgres:  # 服务名字
    image: postgres # 服务需要的docker镜像与docker run命令中的镜像指定方式一致
    volumes:        # 挂载卷,这里的主要目的是,方便同步数据库和数据脚本
      - ./postgres:/var/lib/postgresql/data
      - ./sh:/usr/src/sh
    ports:          # 端口绑定
      - 5433:5432
    container_name: postgres
    environment:    # 设置环境变量
      POSTGRES_PASSWORD: "minepwd"
      POSTGRES_USER: "mineusr"
      POSTGRES_DB: "minedb"
  mineserver:
    image: me/mineserver
    volumes:        # 挂载卷,方便查看输出日志
      - ./logs:/usr/src/mineserver/logs
    ports:
      - 9091:9091
    container_name: mineserver
    links:          # 容器互联
      - postgres:postgres

在编写docker-compose.yml的时候,需要注意的是各个选项的数据类型,不过docker-compose会有提示,也很方便

...

RN历险记

RN

讲述配置ReactNative的心酸历程

程序猿长征第一步 #

根据官方文档来安装RN, 以及巨大无比的Xcode Ver9.0.0

错误一:Build Fail #

可能描述不太一致, 但是原因都差不多, 文件缺失。 菜鸟想必看到这些个报错, 两眼一懵逼, 啥子情况, 怎么和官方的描述不一致, 一个及其简单的RN-Demo, 我就是想跑一下的喂!

我遇到的情况, 分为两种:

其一是安装很慢, 之后失败 其二是安装很快, 然后失败

经过反复的“瞎子”调整, 在多次更换react, react-native版本, 求助Google大叔无果之后。我开始了阅读输出日志的漫漫长路, 终于发现了build失败的元凶, boost/xxx.hpp not found为啥找不到呢, 去文件夹一看, 才发现这些文件真的不存在……

好了知道错误, 就再Google下咯(其实我还去改过这些#includ<boost/config/user.hpp> 0<~>0)这里就直接给出我找的结果吧: http://cdn2.jianshu.io/p/2ef019a7e82a

总的说来, 就是自动下载的的第三方库是残缺的

错误二:CFBundleIdentifier not Found #

第二错误也是困扰了比较多人, 我遇到的只是导致这个情况的其中之一

通过查看输出日志, 并没有发现什么有用的信息, 提示的是Command Fail , balabala… 手动搜索了一下PlistBuddy, 了解了下用法, 然后我手动执行了下命令, 居然可以!!!!什么情况, 那为什么提示错误信息?果断进入到文件夹中查看,果然文件是存在的那么为啥一个可以, 一个不可以呢?到这里, 大致猜到原因了, 没有找到文件

再次以此为点求助Google大叔: http://blog.csdn.net/ohyeahhhh/article/details/54691512

这个坑就是, Xcode编译保存的路径和react-native-cli寻找的路径不一致, 通过修改路径就OK啦, 还有其他原因导致的这个fail 请参阅链接, 先搞清楚react-native run-ios做了啥事.

...

访问量 访客数