简单分布式架构(附源码)

一、项目简介
使用Oracle、Tomcat、Modjk、SpringMVC、Hibernate3、ActiveMQ技术搭建一个(最)简单的分布式小说爬虫系统。
二、项目架构图
这里写图片描述
三、服务器介绍和核心代码
爬虫服务器(spider):使用jsoup进行网页内容爬取,分析文章标题,内容进行存库(原始数据服务器),发送消息通知ActiveMQ,原始数据服务器中有新的需要进行数据清洗的数据。

/**
     * 
     *
     *<p>Description:JSOUP爬取小说</p>
     *
     * @author:SongJia
     *
     * @date: 2017-3-30下午5:29:25
     *
     * @param url
     * @return
     */
    @SuppressWarnings("deprecation")
    @RequestMapping(value = "getnovels")
    @ResponseBody
    public String getNovels(String url){
            try {
            NovelInitial novelBean = new NovelInitial();
            Document doc = Jsoup.connect(url).timeout(10000).get();
            String id = UUID.randomUUID().toString().replace("-", "");
                //小说内容
                String content = doc.getElementById("content").text();
                //小说标题
                String title = doc.getElementsByTag("H1").toString();
                //下一页连接
                 Element nextElement = doc.getElementById("pager_next");
                 String nextUrl = nextElement.attr("href");
                 novelBean.setId(id);
                 novelBean.setTitle(title);
                 novelBean.setCurrentUrl(url);
                 novelBean.setNextUrl(nextUrl);
                 Blob createBlob = Hibernate.createBlob(content.getBytes());
                 novelBean.setContent(createBlob);
                 novelBean.setFlag("1");
                 System.out.println(content);
                 //存入数据库
                 novelService.save(novelBean);
                 //将此篇小说ID发送至MQ,通知处理程序进行小说内容错乱格式进行处理
                 SendMessage.send("{\"id\":\""+id+"\",\"title\":\""+title+"\"}");
                 return nextUrl;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

ActiveMQ服务器(active):通知数据清洗服务器,原始数据服务器中有需要数据清洗服务器进行数据清洗的数据。

/**
     * 
     *
     *<p>Description:消费者,从MQ获取消息</p>
     *
     * @author:SongJia
     *
     * @date: 2017-3-30上午11:39:57
     *
     * @param args
     */
    public static void main(String[] args) {
        // ConnectionFactory :连接工厂,JMS 用它创建连接  
        ConnectionFactory connectionFactory;  
        // Connection :JMS 客户端到JMS Provider 的连接  
        Connection connection = null;  
        // Session: 一个发送或接收消息的线程  
        Session session;  
        // Destination :消息的目的地;消息发送给谁.  
        Destination destination;  
        // 消费者,消息接收者  
        MessageConsumer consumer; 
        Properties prop = MyProperties.init();
        String activemqHost = prop.getProperty("activemq_host");
        String activemqPort = prop.getProperty("activemq_port");
        connectionFactory = new ActiveMQConnectionFactory( ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, "tcp://"+activemqHost+":"+activemqPort);  
        try {  
            // 构造从工厂得到连接对象  
            connection = connectionFactory.createConnection();  
            // 启动  
            connection.start();  
            // 获取操作连接  
            session = connection.createSession(Boolean.FALSE,Session.AUTO_ACKNOWLEDGE);  
            // 获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置  
            destination = session.createQueue("Novel");  
            consumer = session.createConsumer(destination);  
            while (true) {  
                // 设置接收者接收消息的时间,为了便于测试,这里设定为10s  
                TextMessage message = (TextMessage) consumer.receive(10000);  
                if (null != message) {  
                    System.out.println("收到消息" + message.getText()); 
                    //处理消息,提取数据
                    ProcessNovelFormat format = new ProcessNovelFormat();
                    format.formatNovel(message.getText());
                }  

            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            try {  
                if (null != connection)  
                    connection.close();  
            } catch (Throwable ignore) {  
            }  
        }  
    }
/**
 *  
 *
 *<p>Description:MQ调用小说处理程序接口处理小说</p>
 *
 * @author:SongJia
 *
 * @date: 2017-3-30上午11:42:35
 *
 * @param msg
 */
public void formatNovel(String msg){
        Gson gson = new Gson();
        MessageBean bean = gson.fromJson(msg, new TypeToken<MessageBean>(){}.getType());
        String url = "http://localhost:8080/process/process/processnovel?";
        String result = HttpRequestUtil.sendGet(url,bean, "UTF-8");
        System.out.println("处理程序返回的结果:"+result);

    }

数据清洗服务器(process):进行数据清洗(去除文章中的乱码,非法字符),清洗完成之后,进行数据存库(数据服务器)。

@RequestMapping(value = "processnovel")
    @ResponseBody
    public String processNovel(HttpServletRequest request, HttpServletResponse response,String id){
        MessageBean<NovelProcess> bean = new MessageBean<NovelProcess>();
        Gson gson = new Gson();
        try {
            NovelInitial novelInitial = (NovelInitial)novelService.findById(NovelInitial.class, id);
             //对文章进行处理,去除特殊字符
             String content = new String(novelInitial.getContent().getBytes((long)1, (int)novelInitial.getContent().length()));  
             System.out.println("处理之前:"+content);
             String processContent = content.replace("?", "");
             System.out.println("处理之后:"+processContent);
             //存入到新表
             NovelProcess process = new NovelProcess();
             process.setId(novelInitial.getId());
             process.setCurrentUrl(novelInitial.getCurrentUrl());
             @SuppressWarnings("deprecation")
             Blob createBlob = Hibernate.createBlob(processContent.getBytes());
             process.setContent(createBlob);
             process.setName("斗破苍穹");
             process.setFlag(novelInitial.getFlag());
             process.setNextUrl(novelInitial.getNextUrl());
             process.setTitle(novelInitial.getTitle());
             novelService.save(process);
             bean.setCode("0");
             bean.setMessage("ProcessSuccess");
             //如果MessageBean生成private static final long serialVersionUID = 1L; 转JSON的时候会报错!
             String json = gson.toJson(bean,new TypeToken<MessageBean<NovelProcess>>(){}.getType());
             return json;
        } catch (SQLException e) {
             bean.setCode("1");
             bean.setMessage("ProcessSuccess");
             //如果MessageBean生成private static final long serialVersionUID = 1L; 转JSON的时候会报错!
             String json = gson.toJson(bean,new TypeToken<MessageBean<NovelProcess>>(){}.getType());
             return json;
        }
    }

应用服务器:提取数据服务器中的数据,给客户端提供展示所需数据接口,应用服务器使用Modjkh和Tomcat进行简单负载均衡。
大家都应该能写出来吧!!!
四 总结
这四个服务器代码都非常的简单,稍微有点难度的就是写HTTP请求的工具类,然后就是SpringMVC和Hibernate环境整合,其次就是Hibernate对Oracle数据库中Blob数据的存取,这里只是提供很简单的一个例子。
这个程序进行稍微的进化,就比较厉害了,比如把爬虫服务换成Python,把数据清洗服务器换成NLP等等。
五 源码地址
http://download.csdn.net/download/u013292160/9799295

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值