前言
Webdis 是一个非常简单的 Web 服务器,专门为 Redis 提供 HTTP 接口,使用 hiredis、jansson、libevent、http-parser 等组件。下面将介绍 Docker 安装部署 Webdis 与 Redis,由于篇幅有限不会详细介绍部署过程,但会给出 Docker 相关的主要配置内容。如需更详细的教程内容,可参考 Webdis Github 上的说明文档。
软件环境
环境名称 版本 docker-ce 18.09.3 docker-compose 1.24.0-rc1 linux 发行版 CentOS Linux release 7.6.1810 (Core)
Webdis 镜像的 DockerFile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 from debian:stretchMAINTAINER clay<clay@gmail.com>RUN cp /etc/apt/sources.list /etc/apt/backup.sources.list RUN echo "deb http://mirrors.aliyun.com/debian/ stretch main non-free contrib" > /etc/apt/sources.list RUN echo "deb http://mirrors.aliyun.com/debian-security stretch/updates main" >> /etc/apt/sources.list RUN echo "deb http://mirrors.aliyun.com/debian/ stretch-updates main non-free contrib" >> /etc/apt/sources.list RUN echo "deb http://mirrors.aliyun.com/debian/ stretch-backports main non-free contrib" >> /etc/apt/sources.list RUN apt-get -y update && apt-get -y upgrade RUN apt-get -y install apt-utils vim net-tools telnet git curl wget make gcc libevent-dev RUN apt-get -y autoclean && apt-get -y autoremove ENV version 0.1 .4 WORKDIR /usr/local RUN wget --no-check-certificate https://github.com/nicolasff/webdis/archive/$version .tar.gz -O webdis-$version .tar.gz RUN tar -xvzf webdis-$version .tar.gz RUN cd webdis-$version && make && make install && cd .. RUN rm -rf webdis-$version .tag.gz WORKDIR /usr/local /webdis-$version EXPOSE 7379 CMD /usr/local /bin/webdis /etc/webdis.prod.json && bash
构建 Webdis 镜像
1 2 3 4 5 6 7 8 # touch Dockerfile-Webdis# vim Dockerfile-Webdis# docker build -f Dockerfile-Webdis -t clay/webdis:0.1.4 .
Redis 的配置文件
Redis 配置文件中的主要内容(redis.conf)如下:
1 2 3 4 5 # bind 127.0.0.1requirepass C6v8TMQv@oc%4HkznfKJ5jy&zBUencAL
Webdis 的配置文件
Webdis 配置文件(webdis.prod.json)的完整内容如下,具体的 ACL 规则可参考 Github 上的说明文档。考虑到服务器安全,下面配置了 Http Auth 的用户名和密码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 { "redis_host" : "172.89.0.2" , "redis_port" : 6379 , "redis_auth" : "C6v8TMQv@oc%4HkznfKJ5jy&zBUencAL" , "http_host" : "0.0.0.0" , "http_port" : 7379 , "threads" : 4 , "daemonize" : false , "database" : 0 , "acl" : [ { "disabled" : ["DEBUG" , "FLUSHDB" , "FLUSHALL" , "GET" , "SET" , "DEL" ] }, { "http_basic_auth" : "admin:123456" , "enabled" : ["DEBUG" , "GET" , "SET" , "DEL" ] } ], "verbosity" : 3 , "logfile" : "/var/log/webdis.log" }
Docker-Compose 的配置文件
使用 Docker-Compose 管理容器,其中 docker-compose.yml 配置文件的完整内容如下(包括 Redis、Webdis)。具体的数据卷挂载目录,需要根据自己的实际情况进行修改。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 version: "3.5" services: redis: image: redis:5.0 .4 -stretch container_name: redis-5.0 .4 privileged: false ports: - 6379 :6379 networks: redis-network: ipv4_address: 172.89 .0.2 volumes: - '/container/redis/data:/data' - '/container/redis/redis.conf:/usr/local/etc/redis/redis.conf' command: redis-server /usr/local/etc/redis/redis.conf webdis: image: clay/webdis:0.1 .4 container_name: webdis privileged: false depends_on: - redis networks: redis-network: ipv4_address: 172.89 .0.3 ports: - 7379 :7379 volumes: - '/container/wedis/webdis.log:/var/log/webdis.log' - '/container/wedis/webdis.prod.json:/etc/webdis.prod.json' networks: redis-network: name: redis-network driver: bridge ipam: config: - subnet: 172.89 .0.0 /24
创建并启动 Docker 容器
1 2 3 4 5 6 7 8 9 10 11 # cd docker-compose-dir# docker -compose up -d # docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ebd5cac7fee9 clay/webdis:0.1.4 "/bin/sh -c '/usr/lo…" 14 minutes ago Up 14 minutes 0.0.0.0:7379->7379/tcp webdis 9a1feb971d1c redis:5.0.4-stretch "docker-entrypoint.s…" 14 minutes ago Up 14 minutes 0.0.0.0:6379->6379/tcp redis-5.0.4
CURL 命令测试 Webdis 与 Redis 是否正常工作
1 2 3 4 5 6 7 8 9 10 11 # curl http://127.0.0.1:7379/SET/hello/world -u admin:123456{"SET" :[true ,"OK" ]} # curl http://127.0.0.1:7379/GET/hello -u admin:123456{"GET" :"world" } # curl http://127.0.0.1:7379/DEL/hello -u admin:123456{"DEL" :1}
NodeJS 代码测试 Webdis 与 Redis 是否正常工作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 var request = require ('request' );var username = "admin" ;var password = "123456" ;var url = 'http://127.0.0.1:7379/GET/hello' ;var auth = "Basic " + new Buffer(username + ":" + password).toString("base64" );request({ url : url, headers : { "Authorization" : auth } }, function (error, response, body ) { if (error) { console .log(error); return ; } if (response.statusCode == 200 ) { console .log("result: " + body); } else { console .log("code: " + response.statusCode); } } );
WebSocket 与 Pub/Sub 的支持
Webdis 默认不启用 WebSocket 与 Pub/Sub 的支持,如需要相关功能,可以参考以下的步骤进行操作。官方声明 Websocket 与 Pub/Sub 功能是实验性的,生产环境慎用。经过反复测试,按照下面的步骤进行操作,JavaScript 代码依然无法连接 WebSocket、Pub/Sub 服务,后续再想办法解决。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 # docker run -it webdis /bin/bash# cd /usr/local /webdis-0.1.4/tests# tests 目录结构介绍|-- Makefile |-- README.tests |-- basic.py |-- bench.sh |-- limits.py |-- pubsub.c |-- websocket.c `-- websocket.html # make $ ./websocket -h Usage: ./websocket [options] Options are: -h host (default = "127.0.0.1" ) -p port (default = 7379) -c threads (default = 4) -n count (number of messages per thread, default = 100000) -v (verbose)$ ./websocket -h 127.0.0.1 -p 7379 -v $ ./pubsub -h Usage: ./pubsub [options] Options are: -h host (default = "127.0.0.1" ) -p port (default = 7379) -r readers (default = 450) -w writers (default = 10) -c channels (default = 1) -n messages (number of messages to read in total, default = 100000)$ ./pubsub -h 127.0.0.1 -p 7379
JavaScript 代码测试 WebSocket 服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 function testJSON ( ) { var jsonSocket = new WebSocket("ws://127.0.0.1:7379/.json" ); jsonSocket.onopen = function ( ) { console .log("JSON socket connected!" ); jsonSocket.send(JSON .stringify(["SET" , "hello" , "world" ])); jsonSocket.send(JSON .stringify(["GET" , "hello" ])); }; jsonSocket.onmessage = function (messageEvent ) { console .log("JSON received:" , messageEvent.data); }; } testJSON();
JavaScript 代码测试 Pub/Sub 服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 var previous_response_length = 0 xhr = new XMLHttpRequest() xhr.open("GET" , "http://127.0.0.1:7379/SUBSCRIBE/hello" , true ); xhr.onreadystatechange = checkData; xhr.send(null ); function checkData ( ) { if (xhr.readyState == 3 ) { response = xhr.responseText; chunk = response.slice(previous_response_length); previous_response_length = response.length; console .log(chunk); } };
Webdis 的 SSL 支持
Webdis 官方默认不支持 SSL,如果需要 SSL 的支持,可以使用 Nginx 作为反向代理服务器,即配置 Nginx 的代理与 SSL 证书,然后将请求转发给 Webdis,这样就可以提高 Webdis 连接的安全性。Nginx 的示例配置内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 server { listen 18379; # Webdis的IP与端口 server_name 172.89.0.3:7379; # SSL证书 ssl on; ssl_certificate /usr/local/nginx/cert/example.cn.crt; ssl_certificate_key /usr/local/nginx/cert/example.cn.key; # SSL性能调优 ssl_session_timeout 10m; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!AESGCM; location / { # 代理 proxy_pass http://$server_name; } }
1 2 # curl https://example.com:18379/GET/hello -u admin:123456