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 不同

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM