zoukankan      html  css  js  c++  java
  • nginx redis试用

    从上一个upload试用 后,现在我们需要上传图片到redis,由于upload模块会缓存到文件夹,后续处理时再从文件夹读取。这样多出来的io操作希望尽量避免的情况下,我们舍弃upload模块,只使用redis模块来完成上传,因为我们暂时不需要处理这些上传数据,就算要处理从redis中拿出来应该会更快。

    安装并运行redis-server,默认的redis-server没有设置密码,且默认127.0.0.1:6379(nginx.conf中redis2_pass的设置对应),我们测试使用默认的就行了。

    $ sudo apt install redis-server
    $ redis-server

    使用redis,我们需要一些模块:redis2-nginx-module, redis2需要用到set-misc-nginx-module,而这个set-misc-nginx模块需要ngx-devel-kit模块。

    下载上述3个模块并提取(我的模块存放目录:/home/dyan/OpenSource/workspace/nginx-modules)

    nginx源码重新编译一下 (nginx源码目录/home/dyan/OpenSource/nginx-1.4.2),在该目录下编译

    $ ./configure --add-module=/home/dyan/OpenSource/workspace/nginx-modules/redis2-nginx-module-master
    --add-module=/home/dyan/OpenSource/workspace/nginx-modules/ngx_devel_kit-master
    --add-module=/home/dyan/OpenSource/workspace/nginx-modules/set-misc-nginx-module-master

    nginx已经安装到/usr/local/nginx下

    然后修改/usr/local/nginx/conf/nginx.conf(修改前记得先备份),

    但是,这个nginx默认的上传大小限制太小了我们需要对http字段修改client_header_buffer_sizeclient_body_buffer_size的限制。

    client_body_buffer_size 1024k;
    client_header_buffer_size 1024k; #这个是为了方便我们测试,redis2模块上传功能时直接把数据放到header中,这样似乎不合理

    在http字段server字段中添加如下配置

        #$curl "localhost/get?key=ask"
        location = /get {
            set_unescape_uri $key $arg_key;
            redis2_query get $key;
            redis2_pass 127.0.0.1:6379;
            }
        #$curl "localhost/set?key=ask&val=answer"
        location = /set {
            set_unescape_uri $key $arg_key;
            set_unescape_uri $val $arg_val;
            redis2_query set $key $val;
            redis2_pass 127.0.0.1:6379;
        }

    这时确认新的配置没有问题后重载nginx配置

    $ sudo /usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
    nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
    nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
    
    $ ps -ef|grep nginx
    root      9111  3070  0 8月01 ?        00:00:00 nginx: master process sbin/nginx
    dyan     28862  9111  0 22:57 ?        00:00:00 nginx: worker process
    dyan     30167  6058  0 23:50 pts/19   00:00:00 grep --color=auto nginx
    $ sudo kill -HUP 9111

    查看效果,

    $ curl "localhost/set?key=hello&val=world"
    +OK
    $ curl "localhost/get?key=hello"
    $5 #这里的$不是shell,是redis的返回值部分
    world

     附上一个demo_redis_set.cpp检验redis的set功能

    //demo_redis_set.cpp
    #include <curl/curl.h> #include <iostream> #include <sstream> #include <string.h> #include <hiredis/hiredis.h> using namespace std; size_t write_data(void* ptr, size_t size, size_t nmemb, void* stream) { string data((const char*) ptr, (size_t) size * nmemb); *((stringstream*) stream) << data << endl; return size * nmemb; } int main() { FILE *fp = fopen("test8.png","rb"); if(NULL == fp) { cout<<"open file failed"<<endl; return -1; } fseek(fp,0,SEEK_END); size_t file_len = ftell(fp); fseek(fp,0,SEEK_SET); char *data = new char[file_len]; fread(data,1,file_len,fp); fclose(fp); CURL *m_curl = curl_easy_init(); cout<<"file_len:"<<file_len<<endl; char *encode_data = curl_easy_escape(m_curl,data,file_len); // cout<<"encode len:"<<encode_data<<endl; string url="localhost/set"; url += "?key=inquire&val="; url += encode_data;
      //释放curl_easy_escape分配的内存
    curl_free(encode_data); cout
    <<url.length()<<endl; stringstream ssanswer; curl_easy_setopt(m_curl,CURLOPT_SSL_VERIFYPEER,false); curl_easy_setopt(m_curl,CURLOPT_URL,url.c_str()); curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, write_data); curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &ssanswer); CURLcode res = curl_easy_perform(m_curl); string ans = ssanswer.str(); cout<<ans<<endl; //redis 连接 struct timeval timeout = {2, 0}; //2s的超时时间 //redisContext是Redis操作对象 redisContext *pRedisContext = (redisContext*)redisConnectWithTimeout("127.0.0.1", 6379, timeout); if ( (NULL == pRedisContext) || (pRedisContext->err) ) { if (pRedisContext) { std::cout << "connect error:" << pRedisContext->errstr << std::endl; } else { std::cout << "connect error: can't allocate redis context." << std::endl; } return -1; } //redisReply是Redis命令回复对象 redis返回的信息保存在redisReply对象中 redisReply *pRedisReply = (redisReply*)redisCommand(pRedisContext, "get inquire"); //执行INFO命令 int decode_len=0; cout<<"pRedisReply->len:"<<pRedisReply->len<<endl; FILE *fw = fopen("output3.png","wb"); if(NULL == fw) { cout<<"open file failed"<<endl; return -1; } cout<<"redis data len:"<<pRedisReply->len<<endl; int ret = fwrite(pRedisReply->str,1,pRedisReply->len,fw); cout<<"write len:"<<ret<<endl; fclose(fw); //当多条Redis命令使用同一个redisReply对象时 //每一次执行完Redis命令后需要清空redisReply 以免对下一次的Redis操作造成影响 freeReplyObject(pRedisReply); delete[] data; delete[] encode_data; return 0; }

    编译并执行,

    $ g++ -g demo_redis_set.cpp -o test -lcurl -lhiredis -std=c++11
    $ ./test
    file_len:41558
    104068
    +OK
    
    
    pRedisReply->len:41558
    redis data len:41558 
    write len:41558

    看上去一切正常,最后比较一下输入文件与输出文件

    $ diff test8.png output3.png
      #结果返回是一个空行,说明这2个文件是相同的。如果不同就会返回:二进制文件 test8.png 和 output3.png 不同
  • 相关阅读:
    React中条件渲染
    React 中this.setStat是批量执行的, 它发现做三次是多余的,所以只执行一次
    React 修改获取state中的值
    POJ3417 Network (树上差分)
    POJ3349 Snowflake Snow Snowflakes(Hash)
    Codeforces Round #630 (Div. 2) C. K-Complete Word(字符串)
    Codeforces Round #630 (Div. 2) B. Composite Coloring(数论)
    Codeforces Round #630 (Div. 2) A. Exercising Walk(水题)
    Codeforces Round #629 (Div. 3)/1328 E.Tree Queries(LCA)
    洛谷P5836 [USACO19DEC]Milk Visits S(LCA/并查集)
  • 原文地址:https://www.cnblogs.com/dyan1024/p/9436681.html
Copyright © 2011-2022 走看看