ActiveMQ在分布式项目中的实际应用(配合solr和freemarker)

具体需求:

后台添加商品后,需要执行两个操作:

        1.同步索引库(商品搜索使用了Solr实现)

        2.生成静态页面(使用freemarker)

实现构思:

    使用消息队列。MQ作为消息中间件,传递的消息内容为新增商品的ID。

ActiveMQ在分布式项目中的实际应用(配合solr和freemarker)_第1张图片

准备工作:

        在需要的地方添加相应的依赖(基础依赖就不再说了)

        商品服务需要发送商品添加消息,所以需要添加三个依赖,分别是整合Spring需要的两个Jar和ActiveMQ的Jar:


	org.springframework
	spring-jms


	org.springframework
	spring-context-support


	org.apache.activemq
	activemq-all

        索引服务需要接收消息,然后同步索引库,所以需要添加四个依赖,分别是整合Spring需要的两个Jar和ActiveMQ的Jar和Solr客户端的Jar:


	org.springframework
	spring-jms


	org.springframework
	spring-context-support


	org.apache.activemq
	activemq-all


	org.apache.solr
	solr-solrj

        商品详情工程需要就收消息,然后生成静态页面,所以需要添加四个依赖,分别是整合Spring需要的两个Jar和ActiveMQ的Jar和Solr客户端的Jar:


	org.springframework
	spring-jms


	org.springframework
	spring-context-support


	org.apache.activemq
	activemq-all


        org.freemarker
        freemarker

具体实现:

1.商品服务添加商品信息后,发布商品添加消息

spring-activemq.xml



	




	
	





	
	

	


	

ItemServiceImpl.java

@Autowired
private JmsTemplate jmsTemplate;
@Resource // 默认通过id注入,找不到再通过类型注入
private Destination topicDestination; 

@Override
public E3Result addItem(TbItem item, String desc, String itemParams) {
	// 生成商品ID
	final long itemId = IDUtils.genItemId();
	
	/**
	 * 将商品信息插入数据库中
	 */
	
	// 发送一个商品添加消息
	jmsTemplate.send(topicDestination, new MessageCreator() {
		
		@Override
		public Message createMessage(Session session) throws JMSException {
			TextMessage textMessage = session.createTextMessage(itemId + "");
			return textMessage;
		}
	});
	// 返回成功
	return E3Result.ok();
}

2.索引服务配置监听器,接收到商品添加消息后,同步索引库

ItemAddMessageListener.java

public class ItemAddMessageListener implements MessageListener {
	
	@Autowired
	private ItemMapper itemMapper;
	@Autowired
	private SolrServer solrServer;
	
	@Override
	public void onMessage(Message message) {
		try {
			// 从消息中取商品ID
			TextMessage textMessage = (TextMessage) message;
			String text = textMessage.getText();
			Long itemId = new Long(text);
			// 等待事务提交,不等待的话有可能下面会查不到商品信息
			Thread.sleep(1000);
			// 根据商品ID查询商品信息
			SearchItem searchItem = itemMapper.getItemById(itemId);
			// 创建一个文档对象
			SolrInputDocument document = new SolrInputDocument();
			// 向文档对象中添加域
			document.addField("id", searchItem.getId());
			document.addField("item_title", searchItem.getTitle());
			document.addField("item_sell_point", searchItem.getSell_point());
			document.addField("item_price", searchItem.getPrice());
			document.addField("item_image", searchItem.getImage());
			document.addField("item_category_name", searchItem.getCategory_name());
			// 把文档对象写入索引库
			solrServer.add(document);
			// 提交
			solrServer.commit();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

spring-activemq.xml



	




	
	




	

	





	
	
	

3.商品详情工程配置监听器,接收到商品添加消息后,生成商品详情静态页面

        首先需要配置用于生成静态页面的模板,具体的配置方法请参看FreeMarker教程,在这里就不详细叙述了,我这里配置好的模板如下:

ActiveMQ在分布式项目中的实际应用(配合solr和freemarker)_第2张图片    item.ftl是商品详情页面,其他的几个ftl是include进去的,都需要配置。

FreeMarker的配置:



	
	

监听器:

public class HtmlGenListener implements MessageListener {

	@Autowired
	private ItemService itemService;
	@Autowired
	private FreeMarkerConfigurer freeMarkerConfigurer;
	@Value("${HTML_GEN_PATH}")
	private String HTML_GEN_PATH; // 生成的静态页面保存的位置
	
	@Override
	public void onMessage(Message message) {
		try {
			// 从商品中取商品ID
			TextMessage textMessage = (TextMessage) message;
			String text = textMessage.getText();
			Long itemId = new Long(text);
			// 等待事务提交(防止还未插入数据库就查询)
			Thread.sleep(1000);
			// 根据商品id查询商品信息,商品基本信息和商品描述信息
			TbItem tbItem= itemService.getItemById(itemId);
			Item item = new Item(tbItem);
			item.setPrice(item.getPrice() / 100); // 转换价格
			// 取商品描述
			TbItemDesc itemDesc = itemService.getItemDesc(itemId);
			// 创建一个数据集,将模板所需的数据全部放进去
			Map data = new HashMap<>();
			data.put("item", item);
			data.put("itemDesc", itemDesc);
			// 加载模板对象
			Configuration configuration = freeMarkerConfigurer.getConfiguration();
			Template template = configuration.getTemplate("item.ftl");
			// 创建一个输出流,指定输出的目录以及文件名
			Writer out = new FileWriter(HTML_GEN_PATH + itemId + ".html");
			// 生成静态页面
			template.process(data, out);
			// 关闭流
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

引用外部文件:


监听器配置:



	




	
	




	






	
	
	
        至此,功能就实现了。

功能测试

        首先查看一下索引库,可以看到目前有943条商品数据

ActiveMQ在分布式项目中的实际应用(配合solr和freemarker)_第3张图片

        添加商品:

ActiveMQ在分布式项目中的实际应用(配合solr和freemarker)_第4张图片

再次查看索引库,可以看到新增加了一条数据,现在有944条数据:

ActiveMQ在分布式项目中的实际应用(配合solr和freemarker)_第5张图片

搜索新添加的商品:,可以看到,已经能够查到了:

ActiveMQ在分布式项目中的实际应用(配合solr和freemarker)_第6张图片

查看商品详情,与本地生成的静态页面进行对比:

ActiveMQ在分布式项目中的实际应用(配合solr和freemarker)_第7张图片

本地生成静态文件:

ActiveMQ在分布式项目中的实际应用(配合solr和freemarker)_第8张图片

访问本地静态文件(这里使用了Nginx服务器访问静态文件)

ActiveMQ在分布式项目中的实际应用(配合solr和freemarker)_第9张图片

        可以对比一下,两个绝对是一模一样的,这样以后用户访问商品详情的时候就可以返回给其一个静态页面,大大减小了服务器压力,访问速度加快,也提升了用户体验。


你可能感兴趣的:(Solr,ActiveMQ,FreeMarker)