设为首页 收藏本站
查看: 1181|回复: 0

[经验分享] 使用连接池访问memcached(libmemcached)的完整例子

[复制链接]

尚未签到

发表于 2015-11-18 14:14:41 | 显示全部楼层 |阅读模式
  
#include <stdio.h>
#include <libmemcached/memcached.h>
#include <libmemcached/util.h>
#include <assert.h>
  //g&#43;&#43; -m32 -g memcached_test.c -o memcached_test -I/usr/lib/libmemcached/include -L/usr/lib/libmemcached/lib  -lmemcached  -lmemcachedutil
//g&#43;&#43; -m32 -g memcached_test.c -o memcached_test -I/usr/lib/libmemcached/include /usr/lib/libmemcached/lib/libmemcached.a  /usr/lib/libmemcached/lib/libmemcachedutil.a
//gcc -m32 -std=gnu99 -g memcached_test.c -o memcached_test -I/usr/lib/libmemcached/include -L/usr/lib/libmemcached/lib/ -lmemcached  -lmemcached/lib/libmemcachedutil
//不支持 gcc 静态链接方式,因为 pool 实现是 C&#43;&#43; 实现
//gcc -m32 -g memcached_test.c -o memcached_test -I/usr/lib/libmemcached/include /usr/lib/libmemcached/lib/libmemcached.a  /usr/lib/libmemcached/lib/libmemcachedutil.a
///usr/local/memcached-1.4.20/bin/memcached -d -m 10 -u root -l 169.254.10.12 -p 12111
///usr/local/memcached-1.4.20/bin/memcached -d -m 10 -  root -l 169.254.10.12 -p 12112
///usr/local/memcached-1.4.20/bin/memcached -d -m 10 -  root -l 169.254.10.12 -p 12113
  //http://libmemcached.org/libMemcached.html
  //从连接池内取出一个连接集群对象,支持错误码和超时功能
memcached_st * fetch_memcached_wait(memcached_pool_st * pool, struct timespec* wait, memcached_return_t *rc)
{
    assert(pool || wait || rc);
  return memcached_pool_fetch(pool, wait, rc);
}
  //从连接池内取出一个连接集群对象,无空闲对象直接返回
memcached_st * fetch_memcached(memcached_pool_st * pool)
{
    assert(pool);
  static struct timespec wait = { 0, 0 };
    static memcached_return_t rc;
    return fetch_memcached_wait(pool, &wait, &rc);
}
  //释放一个从连接池内取出的一个连接集群对象
void release_memcached(memcached_pool_st * pool, memcached_st *memc)
{
    assert(pool || memc);
  memcached_return_t rc = memcached_pool_push(pool, memc);
    if (MEMCACHED_SUCCESS != rc)
    {
        //printf(&quot;%s\n&quot;, memcached_strerror(0, rc));
    }
}
  //例子程序,通过配置构造一个连接池的种子,构造的对象是一个cache集群
memcached_st * create_memcached_seed_by_config()
{
    const char *config_string = &quot;--SERVER=169.254.10.12:12111/?1 --SERVER=169.254.10.12:12112/?2 --SERVER=169.254.10.12:12113 --CONNECT-TIMEOUT=10&quot;;
    memcached_return_t rc;
    char errmsg[255] = { 0 };
    rc = libmemcached_check_configuration(config_string, strlen(config_string), errmsg, sizeof(errmsg));
    memcached_st *st = 0;
    if (MEMCACHED_SUCCESS != rc)
    {
        printf(&quot;check_configuration fail,%s.%s\n&quot;, errmsg, config_string);
        return st;
    }
  return st = memcached(config_string, strlen(config_string));
}
  
//例子程序,通过服务列表构造一个连接池的种子,构造的对象是一个cache集群
memcached_st * create_memcached_seed_by_srv_list()
{
    const char *hosts[] = { &quot;169.254.10.12&quot;, &quot;169.254.10.12&quot;, &quot;169.254.10.12&quot; };
    size_t port[] = { 12111, 12112, 12113 };
    size_t weight[] = { 1, 2, 1 };
  memcached_server_list_st list = 0;
    bool result = true;
    size_t total = sizeof(weight) / sizeof(size_t);
    for (size_t i = 0; i < total; &#43;&#43;i)
    {
        memcached_return_t rc;
        list = memcached_server_list_append_with_weight(list, hosts, port, weight, &rc);
        if (MEMCACHED_SUCCESS != rc)
        {
            printf(&quot;server_list_append_with_weight fail,%s\n&quot;, memcached_strerror(0, rc));
            result = false;
            break;
        }
    }
  memcached_st *st = 0;
    if (result)
    {
        st = memcached_create(0);
        memcached_server_push(st, list);
        printf(&quot;memcached_server_list_count:%u\n&quot;, memcached_server_list_count(list));
    }
  if (list)
    {
        memcached_server_list_free(list);
    }
    return st;
}
  //例子程序,通过服务直接构造一个连接池的种子,构造的对象是一个cache集群
memcached_st * create_memcached_seed_by_host()
{
    const char *hosts[] = { &quot;169.254.10.12&quot;, &quot;169.254.10.12&quot;, &quot;169.254.10.12&quot; };
    size_t port[] = { 12111, 12112, 12113 };
    size_t weight[] = { 1, 2, 1 };
  bool result = true;
    size_t total = sizeof(weight) / sizeof(size_t);
    memcached_st *st = memcached_create(0);
    assert(st);
    for (size_t i = 0; i < total; &#43;&#43;i)
    {
        memcached_return_t rc;
        rc = memcached_server_add_with_weight(st, hosts, port, weight);
        if (MEMCACHED_SUCCESS != rc)
        {
            printf(&quot;server_add_with_weight fail,%s\n&quot;, memcached_strerror(0, rc));
            result = false;
            break;
        }
    }
  if (!result)
    {
        memcached_free(st);
        st = 0;
    }
    else
    {
        printf(&quot;memcached_server_count,%u\n&quot;, memcached_server_count(st));
    }
    return st;
}
  //例子程序,得到一个cache集群的配置
void get_memcached_config(memcached_st *st)
{
    assert(st);
  uint64_t result = memcached_behavior_get(st, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS);
    printf(&quot;MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS,%llu\n&quot;, result);
  result = memcached_behavior_get(st, MEMCACHED_BEHAVIOR_SND_TIMEOUT);
    printf(&quot;MEMCACHED_BEHAVIOR_SND_TIMEOUT,%llu\n&quot;, result);
  result = memcached_behavior_get(st, MEMCACHED_BEHAVIOR_NO_BLOCK);
    printf(&quot;MEMCACHED_BEHAVIOR_NO_BLOCK ,%lld\n&quot;, result);
  result = memcached_behavior_get(st, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS);
    printf(&quot;MEMCACHED_BEHAVIOR_BUFFER_REQUESTS,%llu\n&quot;, result);
  result = memcached_behavior_get(st, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT);
    printf(&quot;MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT,%llu\n&quot;, result);
  result = memcached_behavior_get(st, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT);
    printf(&quot;MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT,%llu\n&quot;, result);   
}
  //例子程序,设置一个cache集群的配置
void set_memcached_config(memcached_st *st)
{
    assert(st);
   
    memcached_return_t rc;
    rc = memcached_behavior_set(st, MEMCACHED_BEHAVIOR_NO_BLOCK, 1);
    if (MEMCACHED_SUCCESS != rc)
    {
        printf(&quot;set MEMCACHED_BEHAVIOR_NO_BLOCK fail,%s\n&quot;, memcached_strerror(st, rc));
    }
  rc = memcached_behavior_set(st, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000 * 1000 * 3);
    if (MEMCACHED_SUCCESS != rc)
    {
        printf(&quot;set MEMCACHED_BEHAVIOR_RCV_TIMEOUT fail,%s\n&quot;, memcached_strerror(st, rc));
    }
}
  //例子程序,获取一个集群池的配置
void get_memcached_pool_config(memcached_pool_st *pool)
{
    assert(pool);
  uint64_t result = 0;
    memcached_return_t rc;
    rc = memcached_pool_behavior_get(pool, MEMCACHED_BEHAVIOR_NO_BLOCK, &result);
    printf(&quot;MEMCACHED_BEHAVIOR_NO_BLOCK ,%llu\n&quot;, result);
  rc = memcached_pool_behavior_get(pool, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, &result);
    printf(&quot;MEMCACHED_BEHAVIOR_BUFFER_REQUESTS,%llu\n&quot;, result);
  rc = memcached_pool_behavior_get(pool, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, &result);
    printf(&quot;MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT,%llu\n&quot;, result);
  rc = memcached_pool_behavior_get(pool, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, &result);
    printf(&quot;MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT,%llu\n&quot;, result);
  rc = memcached_pool_behavior_get(pool, MEMCACHED_BEHAVIOR_SND_TIMEOUT, &result);
    printf(&quot;MEMCACHED_BEHAVIOR_SND_TIMEOUT,%llu\n&quot;, result);
  
    rc = memcached_pool_behavior_get(pool, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, &result);
    printf(&quot;MEMCACHED_BEHAVIOR_RCV_TIMEOUT,%llu\n&quot;, result);
  
   
    rc = memcached_pool_behavior_get(pool, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS, &result);
    printf(&quot;MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS,%llu\n&quot;, result);
}
  //例子程序,设置一个集群池的配置
bool set_memcached_pool_config(memcached_pool_st *pool)
{
    assert(pool);
  memcached_return_t rc;
    rc = memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000 * 1000 * 3);
    if (MEMCACHED_SUCCESS != rc)
    {
        printf(&quot;MEMCACHED_BEHAVIOR_SND_TIMEOUT fail,%s\n&quot;, memcached_strerror(0, rc));
    }
  rc = memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000 * 1000 * 4);
    if (MEMCACHED_SUCCESS != rc)
    {
        printf(&quot;MEMCACHED_BEHAVIOR_RCV_TIMEOUT fail,%s\n&quot;, memcached_strerror(0, rc));
    }
  rc = memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS, 3);
    if (MEMCACHED_SUCCESS != rc)
    {
        printf(&quot;MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS fail,%s\n&quot;, memcached_strerror(0, rc));
    }   
}
  
//例子程序,一次获取多个key的&#20540;
void mget_memcached(memcached_st *st,const char *keys[], size_t key_length[], size_t key_count)
{
    assert(st || keys || key_length > 0 || key_count > 0);
  uint32_t count = 0, flags = 0;
    char return_key[MEMCACHED_MAX_KEY] = { 0 };
    size_t return_key_length;
    char *return_value = 0;
    size_t return_value_length;
   
    memcached_return_t rc = memcached_mget(st, keys, key_length, key_count);
    while ((return_value = memcached_fetch(st, return_key, &return_key_length,
        &return_value_length, &flags, &rc)))
    {
        count&#43;&#43;;
        printf(&quot;key=%s,keylength=%u,value=%s,total=%u\n&quot;, return_key, return_key_length, return_value, count);
        free(return_value);
        //memset(return_key, 0, sizeof(return_key));
    }
}
  //例子程序,一次获取指定一个key的&#20540;
void get_memcached_by_key(memcached_st *st,const char *key, size_t key_length)
{
    assert(st || key || key_length > 0 );   
  uint32_t flags = 0, value_length = 0;
    memcached_return_t rc;  
    char *value = memcached_get(st, key, key_length, &value_length, &flags, &rc);
    if (MEMCACHED_SUCCESS != rc)
    {
        printf(&quot;%s\n&quot;, memcached_strerror(st, rc));
    }
    else
    {
        printf(&quot;key=%s,key_length=%u,value=%s,value_length=%u\n&quot;, key, key_length, value, value_length);
        free(value);
    }
}
  //完整测试程序
int main(int argc, char *argv[])
{
    printf(&quot;memcached_lib_version:%s\n&quot;, memcached_lib_version());
  //得到一个集群种子,三个方法目的和功能一样,任选一种既可
    memcached_st * memc = create_memcached_seed_by_host();
    //memcached_st * memc = create_memcached_seed_by_srv_list();
    //memcached_st * memc = create_memcached_seed_by_config();
    assert(memc);
  //设置集群种子的属性
    set_memcached_config(memc);
    get_memcached_config(memc);
    printf(&quot;----------\n&quot;);
  //创建集群池,集群池释放,自动释放全部资源(包括种子)
    const uint32_t INITIAL = 1, MAX = 4;
    memcached_pool_st *pool = memcached_pool_create(memc, INITIAL, MAX);
    assert(pool);
  //设置集群种子的属性
    set_memcached_pool_config(pool);
    get_memcached_pool_config(pool);
    printf(&quot;----------\n&quot;);
  //从集群池取出一个集群访问对象
    struct timespec spec = { 3, 0 };
    memcached_return_t rc;
    memc = fetch_memcached_wait(pool, &spec, &rc);
    if (MEMCACHED_SUCCESS != rc)
    {
        printf(&quot;fetch_memcached fail,%s\n&quot;, memcached_strerror(0, rc));        
        memcached_pool_destroy(pool);
        return 0;
    }
  const char *keys[] = { &quot;P&quot;, &quot;1&quot;, &quot;2&quot;, &quot;3&quot;, &quot;a&quot;, &quot;#&quot;, &quot;^&quot;, &quot;*&quot;, &quot;&&quot;, &quot;,&quot;, &quot;?&quot; };
    size_t key_length[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
    const char *values[] = { &quot;11111&quot;, &quot;222b2&quot;, &quot;33333&quot;, &quot;aaaa&quot;, &quot;PPO1&quot;, &quot;OO#&quot;, &quot;^ww&quot;, &quot;***&quot;, &quot;&&&&quot;, &quot;,,,&quot;, &quot;?????&quot; };  
    size_t i = 0, total = sizeof(keys) / sizeof(char *);
    while (memc &&  total > i)
    {
        //设置多个&#20540;,分散存储在多个服务
        rc = memcached_set(memc, keys, strlen(keys), values, strlen(values), 0, 0);
        if (MEMCACHED_SUCCESS != rc)
        {
            printf(&quot;%s,%d\n&quot;, memcached_strerror(memc, rc), i);
        }
        i&#43;&#43;;
    }
  if (memc)
    {
        //释放取出的集群访问对象
        release_memcached(pool,memc);
    }
  //无阻塞,取出一个访问对象
    memc = fetch_memcached(pool);
    //使用不同方式访问对象
    mget_memcached(memc,keys, key_length, sizeof(keys) / sizeof(char *));
    printf(&quot;----------\n&quot;);
    //mget_memcached(memc,keys, key_length, sizeof(keys) / sizeof(char *));
    get_memcached_by_key(memc,keys[10], strlen(keys[10]));
    get_memcached_by_key(memc,keys[4], strlen(keys[4]));
    get_memcached_by_key(memc,keys[3], strlen(keys[3]));
   
    if (memc)
    {
        //释放取出的集群访问对象
        release_memcached(pool, memc);
    }
  //集群池释放, 自动释放全部资源(包括种子)
    memcached_pool_destroy(pool);
  //memcached_return_t rc = MEMCACHED_NOTFOUND;
    //printf(&quot;aa=%s\n&quot;, memcached_strerror(0, rc));
    printf(&quot;over .\n&quot;);
    return 0;
}
  
  
/*
[iyunv@six src]# ./memcached_test
memcached_lib_version:1.0.17
memcached_server_count,3
MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS,5
MEMCACHED_BEHAVIOR_SND_TIMEOUT,0
MEMCACHED_BEHAVIOR_NO_BLOCK ,1
MEMCACHED_BEHAVIOR_BUFFER_REQUESTS,0
MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT,4000
MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT,5
----------
MEMCACHED_BEHAVIOR_NO_BLOCK ,1
MEMCACHED_BEHAVIOR_BUFFER_REQUESTS,0
MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT,4000
MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT,3
MEMCACHED_BEHAVIOR_SND_TIMEOUT,3000000
MEMCACHED_BEHAVIOR_RCV_TIMEOUT,4000000
MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS,3
----------
key=1,keylength=1,value=222b2,total=1
key=2,keylength=1,value=33333,total=2
key=3,keylength=1,value=aaaa,total=3
key=a,keylength=1,value=PPO1,total=4
key=^,keylength=1,value=^ww,total=5
key=,,keylength=1,value=,,,,total=6
key=P,keylength=1,value=11111,total=7
key=#,keylength=1,value=OO#,total=8
key=*,keylength=1,value=***,total=9
key=&,keylength=1,value=&&&,total=10
key=?,keylength=1,value=?????,total=11
----------
key=?,key_length=1,value=?????,value_length=5
key=a,key_length=1,value=PPO1,value_length=4
key=3,key_length=1,value=aaaa,value_length=4
over .
*/
  /*
其中 169.254.10.12:12111有下面的6个key
1,2,3,a,(逗号),,^
  其中 169.254.10.12:12112有下面4个key
P,*,&,#
  其中 169.254.10.12:12113有下面的1个key
?
  */
  
DSC0000.jpg
         版权声明:本文为博主原创文章,未经博主允许不得转载。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-140776-1-1.html 上篇帖子: memcached源码分析-----哈希表基本操作以及扩容过程 下篇帖子: 跨平台 C/C++ memcached 客户端 memcacheclient 介绍
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表