谈一谈CloudBlog的系统架构.docx

上传人:b****2 文档编号:17651058 上传时间:2023-07-27 格式:DOCX 页数:14 大小:308.62KB
下载 相关 举报
谈一谈CloudBlog的系统架构.docx_第1页
第1页 / 共14页
谈一谈CloudBlog的系统架构.docx_第2页
第2页 / 共14页
谈一谈CloudBlog的系统架构.docx_第3页
第3页 / 共14页
谈一谈CloudBlog的系统架构.docx_第4页
第4页 / 共14页
谈一谈CloudBlog的系统架构.docx_第5页
第5页 / 共14页
谈一谈CloudBlog的系统架构.docx_第6页
第6页 / 共14页
谈一谈CloudBlog的系统架构.docx_第7页
第7页 / 共14页
谈一谈CloudBlog的系统架构.docx_第8页
第8页 / 共14页
谈一谈CloudBlog的系统架构.docx_第9页
第9页 / 共14页
谈一谈CloudBlog的系统架构.docx_第10页
第10页 / 共14页
谈一谈CloudBlog的系统架构.docx_第11页
第11页 / 共14页
谈一谈CloudBlog的系统架构.docx_第12页
第12页 / 共14页
谈一谈CloudBlog的系统架构.docx_第13页
第13页 / 共14页
谈一谈CloudBlog的系统架构.docx_第14页
第14页 / 共14页
亲,该文档总共14页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

谈一谈CloudBlog的系统架构.docx

《谈一谈CloudBlog的系统架构.docx》由会员分享,可在线阅读,更多相关《谈一谈CloudBlog的系统架构.docx(14页珍藏版)》请在冰点文库上搜索。

谈一谈CloudBlog的系统架构.docx

谈一谈CloudBlog的系统架构

谈一谈CloudBlog的系统架构

系统整体架构采用分布式的系统,也是当今很多企业都在用的,基于restful风格的一套系统。

从父工程开始blog-parent.这是一个pom工程,主要用来放置pom.xml文件的,这个包含了整个项目所有依赖的jar包。

然后是blog-common,这个存放项目中使用到的一些工具类,也是一个pom工程。

然后是blog-manager工程,这个主要是后台,包括用户操作以及管理员操作,这个项目还有一个积分商城的功能,所以商城的后台我也是放到这个manager工程里面的。

这个manager是一个pom工程,然后下面的mapper和pojo以及service和web都是一个mavenmodule.然后除了blog-manager-web是一个war之外,剩下的三个都是jar工程。

然后前台是blog-portal,还有就是rest、search、sso、order。

rest其实是给积分商城用的。

search使用的是一个solr集群。

因为服务器性能原因,所以我搭建的是三台tomcat的solr集群,依托zookeeper来进行管理。

sso就是单点登录系统,主要给整个系统提供登录服务的。

order系统主要是给积分商城提供订单服务的。

下面来说详细内容:

一、系统后台:

后台是一个easyui的界面,非常简约,写文章的富文本编辑器我采用的是kindeditor。

这个编辑器性能还是不错的,其实使用XX的ueditor富文本编辑器效果也不错,只是因为我的springmvc拦截配置的config一直不成功,于是我就换了其他的编辑器。

数据提交采用的post提交。

[javascript]viewplaincopyprint?

在CODE上查看代码片派生到我的代码片

if(title==null||title==''){

alert("请输入标题!

");

}elseif(typeId==null||typeId==''){

alert("请选择博客类别!

");

}elseif(blogTypeId==null||blogTypeId==''){

alert("请选择博客类别!

");

}elseif(content==null||content==''){

alert("请输入内容!

");

}else{

$.post("/mg/user/blog/save",{'username':

username,'title':

title,'typeid':

typeId,'blogtypeid':

blogTypeId,'content':

content,'summary':

summary,'contentNoTag':

contentNoTag,'keyword':

keyWord},function(result){

if(result.success){

alert("博客发布成功!

");

resetValue();

}else{

alert("博客发布失败!

");

}

},"json");

}

编辑器有一个sync的方法;来将textarea进行同步。

[javascript]viewplaincopyprint?

在CODE上查看代码片派生到我的代码片

varcontent=itemAddEditor.html();

itemAddEditor.sync();

因为这里是加入了lucene全文检索功能,所以在添加或者修改文章的时候,都需要进行索引字段处理,因为富文本编辑器存到数据库中的内容都是带html标签格式的,但是我检索肯定是不需要这些标签的,所以使用下面的方法,来把这个html标签去掉,放到contentNoTag字段,用于检索。

而content就是带html标签的需要存放在数据库的内容。

[javascript]viewplaincopyprint?

在CODE上查看代码片派生到我的代码片

vardd=content.replace(/<\/?

.+?

>/g,"");

varcontentNoTag=dd.replace(/(^\s*)|(\s*$)/g,"");//dds为得到后的内容

然后就是一个列表的查询。

因为这是一个多用户的系统,所以每个用户查看的都是自己的博客信息,所以在查询的时候需要加上用户名。

对于添加博客的时候需要的一个lucene操作。

[java]viewplaincopyprint?

在CODE上查看代码片派生到我的代码片

/**//**

*获取IndexWriter实例

*@return

*@throwsException

*//*

*/privateIndexWritergetWriter()throwsException{

dir=FSDirectory.open(Paths.get("/home/tf/work/data/lucene1/"));

//dir=FSDirectory.open(Paths.get("c:

\\lucene"));

SmartChineseAnalyzeranalyzer=newSmartChineseAnalyzer();

IndexWriterConfigiwc=newIndexWriterConfig(analyzer);

IndexWriterwriter=null;

try{

writer=newIndexWriter(dir,iwc);

}catch(Exceptione){

writer.rollback();

e.printStackTrace();

}

returnwriter;

}

/**//**

*添加博客索引

*@paramblog

*//*

*/publicvoidaddIndex(UBlogblog)throwsException{

IndexWriterwriter=getWriter();

Documentdoc=newDocument();

doc.add(newStringField("id",String.valueOf(blog.getBlogid()),Field.Store.YES));

doc.add(newStringField("username",String.valueOf(blog.getUsername()),Field.Store.YES));

doc.add(newTextField("title",blog.getTitle(),Field.Store.YES));

doc.add(newStringField("releaseDate",DateUtil.formatDate(newDate(),"yyyy-MM-dd"),Field.Store.YES));

doc.add(newTextField("content",blog.getContentNoTag(),Field.Store.YES));

writer.addDocument(doc);

writer.close();

}

而管理员就可以查看所有用户的文章,以及可以进行冻结解冻操作。

后台管理员这里还有一个积分商城,主要是用户发表博客之后又积分,积分可以兑换K币,然后K币可以兑换这个积分商城中的东西。

这个商品添加之后,是不能直接在前台进行查询的,因为我对于这个商品时启用了solr搜索服务的,在我的blog-search工程中做了一个定时任务,在每天凌晨两点进行数据导入操作,系统导入完成之后,就可以在前台查看到添加的这些商品了。

[java]viewplaincopyprint?

在CODE上查看代码片派生到我的代码片

/**

*导入商品数据库到索引库

*/

@Scheduled(cron="002**?

")//每天凌晨两点执行

@RequestMapping("/import")

publicvoidimportAllItems(){

System.out.println("开始执行");

itemService.importAllItems();

System.out.println("执行结束");

}

关于整个后台来说,界面非常简约,需要的功能还是基本上齐全的。

因为是分布式系统的,所以我上线的时候都是分开上线的,在上线后台之后,这个规格参数和商品列表查询一个不能及时刷新$("#itemList").datagrid("reload");我开始以为是数据量太大导致刷新慢,后来发现并不是。

例如我操作了删除,其实数据库中的数据已经删除了,但是这个datagrid却没有反应,查看状态码返回的是304.然后我想到了我后台是启动了CDN缓存加速的,所以我就又跑去看CDN的配置,然后就发现问题了,于是我把列表查询的/mg/item目录的刷新时间设置为0,这样就可以及时刷新,不再是一直在缓存。

这样这个问题就解决了。

通过这个事情我知道,在本地的localhost操作和上线真的是不同的。

在上线过程还遇到了很多在本地操作没有发生的事情,在本地都没有什么问题,一到云服务器上部署,马上问题就来了。

哎!

真是个磨人的小妖精。

二、前台

前台的话基本上也就这样了,因为审美水平问题,只能做到这个样子了,毕竟没有美工,毕竟我是做系统架构和数据处理数据分析的,哎,看来还是有不足之处啊。

我都加入到了Redis缓存中,所以访问速度理论上还是提升了的。

前台页面在CDN缓存设置的是一分钟,所以后台增删改什么的理论上是要过一分钟之后,前台才会更新的。

关于前台的lucene搜索就是:

[java]viewplaincopyprint?

在CODE上查看代码片派生到我的代码片

/**//**

*查询博客信息

*@paramq查询关键字

*@return

*@throwsException

*//*

*/publicListsearchBlog(Stringq)throwsException{

dir=FSDirectory.open(Paths.get("/home/tf/work/data/lucene1/"));

IndexReaderreader=DirectoryReader.open(dir);

IndexSearcheris=newIndexSearcher(eader);

BooleanQuery.BuilderbooleanQuery=newBooleanQuery.Builder();

SmartChineseAnalyzeranalyzer=newSmartChineseAnalyzer();

QueryParserparser=newQueryParser("title",analyzer);

Queryquery=parser.parse(q);

QueryParserparser2=newQueryParser("content",analyzer);

Queryquery2=parser2.parse(q);

booleanQuery.add(query,BooleanClause.Occur.SHOULD);

booleanQuery.add(query2,BooleanClause.Occur.SHOULD);

TopDocshits=is.search(booleanQuery.build(),100);

QueryScorerscorer=newQueryScorer(query);

Fragmenterfragmenter=newSimpleSpanFragmenter(scorer);

SimpleHTMLFormattersimpleHTMLFormatter=newSimpleHTMLFormatter("","");

Highlighterhighlighter=newHighlighter(simpleHTMLFormatter,scorer);

highlighter.setTextFragmenter(fragmenter);

ListblogList=newLinkedList();

for(ScoreDocscoreDoc:

hits.scoreDocs){

Documentdoc=oc(scoreDoc.doc);

UBlogblog=newUBlog();

blog.setBlogid(doc.get(("id")));

blog.setUsername(doc.get("username"));

blog.setReleaseDateStr(doc.get(("releaseDate")));

Stringtitle=doc.get("title");

Stringcontent=StringEscapeUtils.escapeHtml(doc.get("content"));

if(title!

=null){

TokenStreamtokenStream=analyzer.tokenStream("title",newStringReader(title));

StringhTitle=highlighter.getBestFragment(tokenStream,title);

if(StringUtil.isEmpty(hTitle)){

blog.setTitle(title);

}else{

blog.setTitle(hTitle);

}

}

if(content!

=null){

TokenStreamtokenStream=analyzer.tokenStream("content",newStringReader(content));

StringhContent=highlighter.getBestFragment(tokenStream,content);

if(StringUtil.isEmpty(hContent)){

if(content.length()<=200){

blog.setContent(content);

}else{

blog.setContent(content.substring(0,200));

}

}else{

blog.setContent(hContent);

}

}

blogList.add(blog);

}

returnblogList;

}

效果还是不错的,大家可以去试一下,文末提供访问网址。

说到这个文章啊,遇到最头疼的问题就是编码问题了,因为页面展示是一种,然后我mysql数据库的编码,还有redis中存放的文章的编码。

添加缓存的时候又各种进行转换。

都快转晕了,哈哈,当然最终还是解决了,挺开心的。

[java]viewplaincopyprint?

在CODE上查看代码片派生到我的代码片

blog.setContent(newString(blog.getContent().getBytes("iso-8859-1"),

"utf-8"));

商品搜索这边就是调用者blog-search的服务就可以了。

关于这个地方的细节我就不再重复说了,今天只谈架构。

三、Nginx

因为这个系统前后十二个工程,其中mg做为后台,portal做的前台,以及前面说到的各种。

所以我需要一个nginx来处理,主要就是配置端口与域名的映射。

在nginx中进行配置即可。

当然,也是可以直接使用tomcat热部署直接传到服务器中的tomcat中。

当然如果用的是其他中间件服务器的话配置也是类似的。

就是域名端口号说明的。

(为了我服务器的安全,下面配置的端口号我修改了与我真实上线不同的端口号了),你也可以按自己的实际情况配置。

总之还是非常实用和简单的。

[html]viewplaincopyprint?

在CODE上查看代码片派生到我的代码片

upstream{

server139.199.158.214:

9100;

}

upstream{

server139.199.158.214:

9101;

}

upstream{

server139.199.158.214:

9101;

}

upstream{

server139.199.158.214:

9103;

}

[html]viewplaincopyprint?

在CODE上查看代码片派生到我的代码片

server{

listen80;

server_name;

location/{

proxy_pass;

indexindex.htmlindex.htm;

}

}

server{

listen80;

server_name;

location/{

proxy_pass;

indexindex.htmlindex.htm;

}

}

server{

listen80;

server_name;

location/{

proxy_pass;

indexindex.htmlindex.htm;

}

}

server{

listen80;

server_name;

location/{

proxy_pass;

indexindex.htmlindex.htm;

}

}

四、开发中遇到的问题

我遇到最烦人的问题就是这个图片上传的问题,我本来是使用的FTP进行图片上传的。

然后这个磨人的小妖精在本地上传的时候没有任何问题,我一部署到服务器,完了,完全post不上去了,折腾的够呛,一直是什么network什么什么的错误,简直气炸!

我后来慢慢的排查问题,从文件大小限制,nginx配置,cdn缓存配置,服务器权限,还从朋友那里在接了一台tomcat来测试,发现依然是这个问题。

折腾了一天。

然后我就放弃治疗。

UncaughtSecurityError:

Failedtoreadthe'contentDocument'propertyfrom'HTMLIFrameElement':

Blockedaframewithorigin""fromaccessingaframewithorigin"null".Theframerequestingaccesshasaprotocolof"http",theframebeingaccessedhasaprotocolof"data".Protocolsmustmatch.

当然,最后我换了一种方案,本来这个图片是全部要存放到我的ftp图片服务器中的。

既然解决不了怎么办呢,这个图片上传的功能是必须要的啊,于是乎,我突然发现了COS对象存储服务。

简直发现宝有木有。

开始看文档感觉挺复杂的,后来自己折腾了一下,将这个cos的官方代码于我的ftp工具类的代码进行了整合,哎呦喂,居然成功了,1个小时就搞定了。

在这一篇博客中介绍如何使用腾讯云的COS对象存储服务。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2