php和java的memcached使用的兼容性问题解决过程
1. 背景:
php 使用memcached客戶端設置一個key,java使用java-memcached-client去讀,報錯如下:
ERROR|com.whalin.MemCached.MemCachedClient:-1|++++ exception thrown while trying to get object from cache for key: glt7hpcdi1ggo03l9qknu8a755
2. 網上搜索,發現最多的解釋:
在memcached中,不同的客戶端在set或者add值時,對命令的第二個參數的使用是不一致的 <command?name>?<key>?<flags>?<exptime>?<bytes><data?block>
JAVA客戶端flags字段填寫的都是32,不是32的是無法通過java客戶端get出來的
所以在通過memcached?admin進行數據set時,需要顯示指定flags值為32
set?testkey?32?0?5
12345
如此放入緩存后,通過java客戶端是可以取出來的。 3. 可選的解決方案,1)從php端設置flag 2)從java端取的時候使用flag 3)使用別的客戶端繞過這個障礙 。方案1,php端沒有封裝php的memcached客戶端,調用在系統中隨處可見,故該方案不可行,最起碼風險比較大,成本高。方案2,研究了一下使用的memcached客戶端,沒法發現使用flag標示的地方,本身客戶端如果自己去寫的話,風險也不小。方案3,網上有人提到過使用spy memcached client可以避過,故嘗試一下。 4. 解決步驟:
4.0. 增加spymemcached依賴
????????????<dependency> <groupId>net.spy</groupId> <artifactId>spymemcached</artifactId> <version>2.12.0</version> </dependency>
4.1. 配置memcached的ip地址
???分別在dev,test,idc,prod的app-config.properties文件下添加memcached的ip地址:
???dev,test:memcache_ip=192.168.1.10:11211
??idc:memcache_ip=172.16.4.10:11211
?prod:memcache_ip=172.16.0.10:11211
4.2. 配置memcached實例:
app-cached.xml文件增加:
<bean id="springContextHolder" class="com.test.bean.SpringContextHolder" /> <bean id="memcachedClient" class="net.spy.memcached.spring.MemcachedClientFactoryBean"> ?????<property name="servers" value="${memcache_ip}"/> ?????<property name="protocol" value="BINARY"/> ?????<property name="transcoder"> ???????<bean class="net.spy.memcached.transcoders.SerializingTranscoder"> ?????????<property name="compressionThreshold" value="1024"/> ???????</bean> ?????</property> ?????<property name="opTimeout" value="1000"/> ?????<property name="timeoutExceptionThreshold" value="1998"/> ?????<property name="useNagleAlgorithm" value="false"/> ???</bean>
4.3. 新增類SpringContextHolder
import java.util.Map;
import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;
/** * ?* 以靜態變量保存Spring ApplicationContext, 可在任何代碼任何地方任何時候中取出ApplicaitonContext. **/
public class SpringContextHolder implements ApplicationContextAware {
?private static ApplicationContext applicationContext;
?/** * ?* 實現ApplicationContextAware接口的context注入函數, 將其存入靜態變量. */
?public void setApplicationContext(ApplicationContext applicationContext) {
?SpringContextHolder.applicationContext = applicationContext;
?}
?/** * ?* 取得存儲在靜態變量中的ApplicationContext. */
?public static ApplicationContext getApplicationContext() {
?checkApplicationContext();
?return applicationContext;
?}
?/** * ?* 從靜態變量ApplicationContext中取得Bean, 自動轉型為所賦值對象的類型. */
?@SuppressWarnings("unchecked") public static <T> T getBean(String name) {
?checkApplicationContext();
?return (T) applicationContext.getBean(name);
?}
?/** * ?* 從靜態變量ApplicationContext中取得Bean, 自動轉型為所賦值對象的類型. * ?* 如果有多個Bean符合Class, 取出第一個. */
?@SuppressWarnings("unchecked") public static <T> T getBean(Class<T> clazz) {
?checkApplicationContext();
?Map beanMaps = applicationContext.getBeansOfType(clazz);
?if (beanMaps != null && !beanMaps.isEmpty()) {
?return (T) beanMaps.values().iterator().next();
?} else {
?return null;
?}
?}
?private static void checkApplicationContext() {
?if (applicationContext == null) {
?throw new IllegalStateException("applicaitonContext未注入,請在applicationContext.xml中定義SpringContextHolder");
?}
?}
}
4.4.增加MemcacheUtil?
import com.test.bean.SpringContextHolder;import net.spy.memcached.MemcachedClient;
public class MemcacheUtil { ???public static MemcachedClient getMemCachedClient() { ???????return SpringContextHolder.getBean("memcachedClient");}}
4.5 測試代碼
public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( "classpath:spring-memcached-spy.xml"); MemcachedClient client=MemcacheUtil.getMemCachedClient(); ?//MemcachedClient client =(MemcachedClient)context.getBean("memcachedClient"); Object obj=client.get("glt7hpcdi1ggo03l9qknu8a755"); ?System.out.println(obj); }
?
注意事項:
使用spy memcached客戶端,在key-value對中,如果value是對象的話,則讀取不到,是string的話則可以讀取。故建議使用時key-value約定為string類型。value為對象的話,可以考慮轉成json串。
轉載于:https://www.cnblogs.com/davidwang456/p/5229871.html
總結
以上是生活随笔為你收集整理的php和java的memcached使用的兼容性问题解决过程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: multi-CPU, multi-cor
- 下一篇: 使用ELK(Elasticsearch