`
nkadun
  • 浏览: 55530 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

<实践>Voldemort与Objot集成的WAP高性能方案与简单实现(二)

阅读更多
2、IOC、AOP及请求处理
ServiceHandler.java//负责处理WAP请求分发和初始化存储
public class ServiceHandler {

//URI缓存
	private ConcurrentHashMap<String, ServiceInfo> infos = new ConcurrentHashMap<String, ServiceInfo>(128, 0.8f, 32);
	private Container container;

	public void init(StoreRepository repository) throws Exception {
//初始化Objot容器
		container = Services.build(repository);
	}

	public String handle(ServletRequest request, ServletResponse response) throws Exception {
//解析URI
		String uri = ((HttpServletRequest)request).getRequestURI();
		String name = uri.substring(uri.lastIndexOf('/') + 1);

		ServiceInfo info = getInfo(name);

//处理URL参数,只有一个参数名p,即p=a&p=b&p=c...

		Object[] ps = parse(request.getParameterValues("p"), info.meth.getParameterTypes());
		String result = (String)info.meth.invoke(container.get(info.cla), ps);

//如果有需要填充到页面的数据,则加载
		ModelMap map = ps.length > 0 && ps[ps.length - 1] instanceof ModelMap ? (ModelMap)ps[ps.length - 1] : null;
		if(map != null)
			for(String s : map.keySet())
				request.setAttribute(s, map.get(s));
		return result;
	}

//根据URI解析类名和方法名,包在ServiceInfo中
	private ServiceInfo getInfo(String name) {
		ServiceInfo inf = infos.get(name);
		if(inf != null)
			return inf;
		try {
			int x = String2.index(name, "-", 0);
			inf = getInfo(Class2.packageName(Do.class).concat(".").concat(name.substring(0, x)), String2.sub(name,
					x + 1));
		}
		catch(RequestException e) {
			throw e;
		}
		catch(Exception e) {
			throw new RequestException("Service not found: ".concat(name), e);
		}
		if(inf == null)
			throw new RequestException("Service not found: ".concat(name));
		infos.put(name, inf);
		return inf;
	}

	private ServiceInfo getInfo(String cla, String method) throws Exception {
		Class<?> c = Class.forName(cla);
		if(Mod2.match(c, Mod2.PUBLIC))
			for(Method m : c.getMethods())
				if(m.getName().equals(method))
					return new ServiceInfo(m);
		return null;
	}

//解析HTTP参数,对应到DoX的方法
	private Object[] parse(String[] values, Class<?>[] types) throws Exception {
		int needN = types.length == 0 ? 0 : types[types.length - 1] == ModelMap.class ? types.length - 1 : types.length;
		int paramN = values != null ? values.length : 0;
		if(needN != paramN)
			throw new Exception("Arguments mismatch");
		Object[] os = null;
		if(types.length > 0 && types[types.length - 1] == ModelMap.class) {
			os = new Object[needN + 1];
			os[needN] = new ModelMap();
		}
		else
			os = new Object[needN];
		for(int i = 0; i < needN; i++)
			os[i] = parse(values[i], types[i]);
		return os;
	}

	private static Object parse(String str, Class<?> ct) throws Exception {
		if(ct == int.class)
			return Integer.parseInt(str);
		else if(ct == long.class)
			return Long.parseLong(str);
		else if(ct == String.class)
			return str;
		else
			throw new Exception("Unsupported convertion: java.lang.String -> ".concat(ct.getName()));
	}
}


Services.java//初始化各个服务,编解码器(因为是使用byte[]存储,json或java serial都太慢),使用Objot IOC和AOP(负责打开Voldemort Store)
public class Services {

public static Container build(final StoreRepository repository) throws Exception {

//初始化编解码器,存储用
		final Codec codec = new Codec() {
			String modelPrefix = Class2.packageName(Id.class).concat(".");

			@Override
			protected Object byName(String name, Object ruleKey) throws Exception {
				if(name.length() == 0)
					return HashMap.class;
				return Class.forName(modelPrefix.concat(name));
			}

			@SuppressWarnings("unchecked")
			@Override
			protected String name(Object o, Class<?> c, Object ruleKey) throws Exception {
				if(o instanceof HashMap)
					return "";
				return Class2.selfName(c);
			}
		};

//初始化版本冲突解决器
		final VectorClockInconsistencyResolver<byte[]> resolver = new VectorClockInconsistencyResolver<byte[]>();

		final Weaver w = new Weaver(Transaction.As.class) {
			@Override
			protected Object forWeave(Class<? extends Aspect> ac, Method m) throws Exception {
				if(!m.isAnnotationPresent(Service.class))
					return this;
//是否需要数据操作的AOP
				if(ac == Transaction.As.class)
					return m.isAnnotationPresent(Transaction.Any.class) ? this : null;
				return this;
			}
		};

		final Container sess = new Factory() {
			{
				bind(StoreRepository.class);
				bind(VectorClockInconsistencyResolver.class);
				bind(Codec.class);
			}

			@Override
			protected Object forBind(Class<?> c, Bind b) throws Exception {
				return c == StoreRepository.class ? b.obj(repository) : c == VectorClockInconsistencyResolver.class ? b
						.obj(resolver) : c == Codec.class ? b.obj(codec) : b;
			}
		}.create(null);

		Factory req = new Factory() {
			@Override
			protected Object forBind(Class<?> c, Bind b) throws Exception {
				if(sess.bound(c))
					return b.mode(Inject.Parent.class);
				if(c.isSynthetic())
					return b;
				return b.cla(w.weave(c));
			}
		};

		for(Class<?> c : Class2.packageClasses(Do.class))
			if(Mod2.match(c, Mod2.PUBLIC, Mod2.ABSTRACT))
				req.bind(c);
		return req.create(sess, true);
	}
}


Transaction.java //Any表示不需要数据操作
public @interface Transaction {

	@Retention(RetentionPolicy.RUNTIME)
	@Target(ElementType.METHOD)
	public @interface Any {
	}
//数据操作Aspect
	public static class As extends Aspect {
		@Inject
		public StoreRepository repository;
		@Inject
		public Data data;

		@Override
		protected void aspect() throws Throwable {
			if(data.store == null)
				data.store = repository.getRoutedStore("vortex");
			Target.invoke();
		}
	}
}


Do.java //所有服务的父类
public class Do {

	@Inject
	public Data data;

	@Retention(RetentionPolicy.RUNTIME)
	@Inherited
	public @interface Service {
	}
}


Data.java //Voldemort数据操作类,以VectorClock方式解决版本问题
public class Data {

	public Store<ByteArray, byte[]> store;
	@Inject
	public VectorClockInconsistencyResolver<byte[]> resolver;
	@Inject
	public Codec codec;

	public <T extends Id<T>> void put(T model) throws Exception {
//以id来判定是新加还是更改
		if(model.id <= 0) {
			model.id = nextId(model.getClass());
		}
		ByteArray key = new ByteArray(model.getClass().getSimpleName().concat("::" + model.id).getBytes());
		byte[] value = String2.utf(codec.enc(model, null));
		Versioned<byte[]> v = fix(store.get(key));
		if(v == null)
			v = new Versioned<byte[]>(value);
		else
			v.setObject(value);
		store.put(key, v);
	}

	public <T extends Id<T>> T get(Class<T> c, long id) throws Exception {
		ByteArray key = new ByteArray(c.getSimpleName().concat("::" + id).getBytes());
		Versioned<byte[]> v = fix(store.get(key));
		return codec.dec(String2.utf(v.getValue()), c, null);
	}

//取得Model的id下一个值,自增长方式,多节点会有问题!!!
	public long nextId(Class<?> c) {
		ByteArray counterKey = new ByteArray(c.getSimpleName().concat("-Counter").getBytes());
		long nextId = 1L;
		byte[] id = new byte[8];
		Versioned<byte[]> fix = fix(store.get(counterKey));
		if(fix == null) {
			Bytes.writeS8(id, 0, nextId);
			fix = new Versioned<byte[]>(id);
		}
		else {
			nextId = Bytes.readU8(fix.getValue(), 0) + 1;
			Bytes.writeS8(id, 0, nextId);
			fix.setObject(id);
		}
		store.put(counterKey, fix);
		return nextId;
	}

//解决版本冲突
	private Versioned<byte[]> fix(List<Versioned<byte[]>> vs) {
		if(vs == null || vs.isEmpty())
			return null;
		return resolver.resolveConflicts(vs).get(0);
	}
}
分享到:
评论

相关推荐

    Memcached内存分析、调优、集群

    ### Memcached内存分析、调优、集群:深入理解与实践 #### 1. Memcached背景与概述 Memcached是一款高性能的分布式内存缓存服务器,它最初由LiveJournal的运营人员开发,现已成为开源社区中不可或缺的一部分。其...

    Voldemort271.github.io:..

    这可能使用`&lt;nav&gt;`元素实现,内部嵌套`&lt;ul&gt;`无序列表和`&lt;li&gt;`列表项,每个列表项可能包含一个指向特定项目的`&lt;a&gt;`标签。此外,为了美观和用户体验,可能会用到CSS(层叠样式表)来定制布局和样式,使页面更具吸引力...

    voldemort 只使用内存作缓存的配置

    它的设计目标是提供高可用性、可扩展性和高性能。在这个配置中,我们关注的是如何将 Voldemort 配置为仅使用内存作为缓存,而不涉及任何持久化机制。 **内存缓存的优势** 内存缓存提供了极快的数据访问速度,因为...

    voldemort,亚马逊发电机的开源克隆。.zip

    Voldemort是一款分布式键值存储系统,它源自亚马逊的 Dynamo 系统,并且作为一个开源项目,为全球的开发者提供了实现高可用、高可扩展性的数据存储解决方案。Voldemort 的设计目标是提供低延迟、高一致性的数据存储...

    Nosql_Voldormort:No Sql-RubiS框架的Voldemort实现

    【标题】Nosql_Voldormort: No Sql-RubiS框架的Voldemort实现 在当前大数据时代,NoSQL数据库因其高可扩展性、高性能和灵活的数据模型,成为了处理大规模数据的重要工具。Voldemort是LinkedIn开源的一款分布式键值...

    redis入门与实践

    ### Redis入门与实践 #### 一、Redis简介与NoSQL概念 Redis是一种广泛使用的开源内存数据结构存储系统,它可以作为数据库、缓存和消息中间件使用。作为一种NoSQL(Not Only SQL)数据库,Redis提供了键值对存储...

    NoSQL数据库学习教程.pdf

    Voldemort是指使用Voldemort来实现分布式系统的可扩展性。 Dynomite是指使用Dynomite来实现分布式系统的可扩展性。 Kai是指使用Kai来实现分布式系统的可扩展性。 应用篇: eBay 架构经验是指使用eBay的架构经验...

    Voldemort:分布式键值存储系统-开源

    Voldemort 是一个分布式数据库,它是亚马逊 Dynamo 的开源克隆。 它自动在多个服务器上复制数据,并自动对它们进行分区,因此每个服务器只包含总数据的一个子集。 它提供了许多其他功能,例如可插拔序列化支持、数据...

    Apache Hadoop Goes Realtime at Facebook

    ### Apache Hadoop 实现Facebook实时计算的关键技术与实践 #### 概述 随着大数据时代的到来,数据处理的需求日益增长,特别是在社交媒体平台如Facebook这样的大型应用上。为了应对这些挑战,Facebook选择采用...

    藏经阁-Storage Infrastructure behind LinkedIn's recommendation-29.p

    LinkedIn 推荐系统存储基础设施概述 在本篇中,我们将深入探讨 LinkedIn 的推荐系统存储基础设施,了解其架构设计、挑战和解决方案。...它具有高性能、高可用性和高扩展性,能够满足 LinkedIn 大规模用户的需求。

    Redis实战.pdf

    3. **memcachedb**:结合了memcached的高性能与传统数据库的数据持久化特性,支持ACID事务。 4. **Cassandra**:一个分布式NoSQL数据库系统,以高度可扩展性和容错性著称。 5. **memcached**:一个简单的内存键值...

    Practical Tips for Using MySQL as a Scalable Key-Value Store

    - **高性能**:NoSQL系统通常针对特定的工作负载进行优化,从而实现更高的吞吐量和更低的延迟。 - **更针对性的API设计**:NoSQL系统通常提供了更为精简和直接的数据访问接口。 - **灵活的模式设计**:支持动态模式...

    Redis实战《红丸出品》

    随着互联网应用规模的不断扩大,传统的关系型数据库难以满足高并发、大数据量的需求,Key-Value Store以其简单高效的数据模型和良好的扩展性,成为解决这些问题的理想方案。此外,云存储的普及也促进了Key-Value ...

    Redis实战文档

    #### 二、Redis核心特性与实践 ##### 2.1 数据类型 Redis不仅仅是一个简单的Key-Value存储系统,它还提供了五种主要的数据类型:字符串(Strings)、散列(Hashes)、列表(Lists)、集合(Sets)和有序集合...

    NoSQL数据库笔谈

    - **Voldemort**: 高性能的分布式键值存储系统。 - **Dynomite**: 分布式的键值存储系统。 - **Kai**: 分布式的键值存储系统。 **10. 未分类** - **Skynet**: 分布式计算平台。 - **Drizzle**: 轻量级的关系型...

    常见数据库场景分析

    - **Sybase**:针对金融行业的高性能解决方案。 - **DB2**:IBM的产品,支持多种操作系统平台。 - **Access**:Microsoft Office组件之一,适用于小型数据库应用。 #### 二、常见非关系型数据库(NoSQL) ##### 1....

    分布式定时任务调度系统技术选型指南.docx

    在选择适合的分布式定时任务调度系统时,我们需要考虑多个因素,包括系统的可扩展性、可靠性、易用性、社区支持以及与现有技术栈的集成能力。 1. **什么是分布式定时任务** 分布式定时任务是一种将原先分散、不...

    深入学习MongoDB

    MongoDB 是一个高性能、开源、无模式的文档型数据库,它在许多场景下可用于替代传统的关系型数据库或键/值存储方式。MongoDB 使用 C++ 开发,不支持 SQL,但有自己功能强大的查询语法。MongoDB 使用 BSON 作为数据...

    《Redis实战》红丸出品

    3. **主从同步**:Redis的主从复制机制可以实现数据的高可用性和读写分离,主节点负责写操作,而从节点则用于读取,大大提高了系统的整体性能和稳定性。 4. **性能优化**:Redis采用了单线程模型和事件驱动架构,...

    Redis心得笔记.docx

    NoSql 是为了解决高并发、高可用、高可扩展、大数据存储等一系列问题而产生的数据库解决方案。NoSql,叫非关系型数据库,它的全名是 Not only sql。它不能替代关系型数据库,只能作为关系型数据库的一个良好补充。 ...

Global site tag (gtag.js) - Google Analytics