【Memcached】实录PHP项目Yii2框架本地Docker-compose部署Memcached的坑/Yii2跨项目使用Memcached的key解决方案/亲测可用带源码建议收藏

给出结论

docker部署的环境在docker内部,如果要在环境内访问,需要在项目配置中使用

	host.docker.internal

千万不能使用

	localhost

本地部署docker-compose文件

本配置包括了

  • nginx
  • php
  • elasticsearch
  • kibana

拿走之后,部署之前,一定要改网段!!!

version: "3"
services:memcached:image: memcached:1.4.32ports:- "11211:11211"networks:web:ipv4_address: 172.25.0.9elastic:image: elasticsearch:6.7.0
#    image: elasticsearch:7.9.3ports:- "9200:9200"environment:- bootstrap.system_call_filter=false
#      - node.name=node-1
#      - cluster.initial_master_nodes=node-1volumes:
#      - /opt/docker/elasticsearch/data:/usr/share/elasticsearch/data- ../elasticsearch-local/data:/usr/share/elasticsearch/datanetworks:web:ipv4_address: 172.25.0.3kibana:image: kibana:6.7.0
#    image: kibana:7.9.3environment:- I18N_LOCALE=zh-CN- ELASTICSEARCH_HOSTS=http://172.25.0.3:9200- ELASTICSEARCH_URL=http://172.25.0.3:9200ports:- "5601:5601"networks:- webphp:image: crunchgeek/php-fpm:7.0volumes:- ./yii_env.php:/var/www/yii_env.php- ./php.ini:/usr/local/etc/php/php.ini- ./:/var/www/htmlnetworks:- webweb:image: nginxports:- "8001-8009:8001-8009"volumes:- ./yii_env.php:/var/www/yii_env.php- ./:/var/www/html- ./default:/etc/nginx/conf.d/default.conf- ./localcerts:/etc/nginx/certsnetworks:- webnetworks:web:ipam:driver: defaultconfig:- subnet: "172.25.0.0/16"

Yii2的Memcached相关配置

这里我继承原来的类,重写了两个方法,后面给出。

原来的类为yii\caching\MemCache

        'memcached' => ['class' => 'common\components\memcached\Connection','servers' => [['host' => 'host.docker.internal', //docker内配置'port' => 11211,'weight' => 100,],],'useMemcached' => true ,],

YIi2下的跨项目使用Memcached的key的解决方案

Cache类中,框架内对key做了封装,源代码如下

    /*** Retrieves a value from cache with a specified key.* @param mixed $key a key identifying the cached value. This can be a simple string or* a complex data structure consisting of factors representing the key.* @return mixed the value stored in cache, false if the value is not in the cache, expired,* or the dependency associated with the cached data has changed.*/public function get($key){$key = $this->buildKey($key);$value = $this->getValue($key);if ($value === false || $this->serializer === false) {return $value;} elseif ($this->serializer === null) {$value = unserialize($value);} else {$value = call_user_func($this->serializer[1], $value);}if (is_array($value) && !($value[1] instanceof Dependency && $value[1]->isChanged($this))) {return $value[0];}return false;}/*** Stores a value identified by a key into cache.* If the cache already contains such a key, the existing value and* expiration time will be replaced with the new ones, respectively.** @param mixed $key a key identifying the value to be cached. This can be a simple string or* a complex data structure consisting of factors representing the key.* @param mixed $value the value to be cached* @param int $duration default duration in seconds before the cache will expire. If not set,* default [[defaultDuration]] value is used.* @param Dependency $dependency dependency of the cached item. If the dependency changes,* the corresponding value in the cache will be invalidated when it is fetched via [[get()]].* This parameter is ignored if [[serializer]] is false.* @return bool whether the value is successfully stored into cache*/public function set($key, $value, $duration = null, $dependency = null){if ($duration === null) {$duration = $this->defaultDuration;}if ($dependency !== null && $this->serializer !== false) {$dependency->evaluateDependency($this);}if ($this->serializer === null) {$value = serialize([$value, $dependency]);} elseif ($this->serializer !== false) {$value = call_user_func($this->serializer[0], [$value, $dependency]);}$key = $this->buildKey($key);return $this->setValue($key, $value, $duration);}

其中,调用了buildKey($key),这样就会导致,实际写入的key并不是真正的key。

    /*** Builds a normalized cache key from a given key.** If the given key is a string containing alphanumeric characters only and no more than 32 characters,* then the key will be returned back prefixed with [[keyPrefix]]. Otherwise, a normalized key* is generated by serializing the given key, applying MD5 hashing, and prefixing with [[keyPrefix]].** @param mixed $key the key to be normalized* @return string the generated cache key*/public function buildKey($key){if (is_string($key)) {$key = ctype_alnum($key) && StringHelper::byteLength($key) <= 32 ? $key : md5($key);} else {if ($this->_igbinaryAvailable) {$serializedKey = igbinary_serialize($key);} else {$serializedKey = serialize($key);}$key = md5($serializedKey);}return $this->keyPrefix . $key;}

所以,我的做法是继承原有类,重写getset方法。

namespace common\components\memcached;class Connection extends \yii\caching\MemCache
{//跳过框架加密key,保证跨项目的缓存共用public function set($key, $value, $duration = 0, $dependency = null){if(is_array($value)){$value = json_encode($value);}return $this->setValue($key, $value, $duration);}public function get($key){$value =  $this->getValue($key);if(is_string($value) && json_decode($value,true)){$value = json_decode($value,true);}return $value;}}

总结

  • 一定要牢记docker的访问范围
  • 多看源码,多思考


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部