下载与ES对应的版本:官网地址解压修改$KIBANA_HOME/config/kibana.yml文件启动Kibana:sudo$KIBANA_HOME/bin/kibana浏览器输入host:5601能正常打开页面即可KAAE插件安装KAAE为Kibana的插件,主要用来监控和报警,用户可以根据需求配置相应的监控条件,达到某个条件会发出报警消息,同时KAAE也提供有报告Report功能,能够将查询到的结果生成图表发送到指定邮箱。安装:$KIBANA_HOME/bin/kibana-pulgininstallhttps://github.com/sirensolutions/sentinl/releases/download/tag-6.2.3-3/sentinl-v6.2.4.zip配置kibana.yml文件,在最后加上:重启Kibana后,浏览器输入:http://ip:5601出现以下界面说明插件安装成功可以在页面上按照需求配置监听报警
Vue+SpringBoot实现WebSocket通信服务端在SpringBoot项目中添加ServerEndpointExporterBean的方法@BeanpublicServerEndpointExporterexporter(){returnnewServerEndpointExporter();}创建WebSocket客户端管理类:WebSocketComponent.javapackagecn.coralcloud.blog.web.component;importcom.alibaba.fastjson.JSON;importorg.springframework.stereotype.Component;importjavax.websocket.*;importjavax.websocket.server.ServerEndpoint;importjava.io.IOException;importjava.util.Objects;importjava.util.concurrent.CopyOnWriteArraySet;/**@authorgeff@nameWebSocketComponent@description@date2019-12-1814:22/@ServerEndpoint(value="/websocket")@ComponentpublicclassWebSocketComponent{/**静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。/privatestaticintonlineCount=0;/**concurrent包的线程安全Set,用来存放每个客户端对应的CumWebSocket对象。/privatestaticCopyOnWriteArraySetwebSocketSet=newCopyOnWriteArraySet<>();/**与某个客户端的连接会话,需要通过它来给客户端发送数据/privateSessionsession;/**连接建立成功调用的方法@paramsessionsession/@OnOpenpublicvoidonOpen(Sessionsession){this.session=session;//加入set中webSocketSet.add(this);//添加在线人数addOnlineCount();System.out.println("新连接接入。当前在线人数为:"+getOnlineCount());}/**连接关闭调用的方法/@OnClosepublicvoidonClose(){//从set中删除webSocketSet.remove(this);//在线数减1subOnlineCount();System.out.println("有连接关闭。当前在线人数为:"+getOnlineCount());}/**收到客户端消息后调用@parammessagemessage@paramsessionsession/@OnMessagepublicvoidonMessage(Stringmessage,Sessionsession){System.out.println("客户端发送的消息:"+message);sendAll(JSON.toJSONString(messageDTO),session.getId());}/**群发@parammessagemessage/privatestaticvoidsendAll(Stringmessage,StringsessionId){webSocketSet.forEach(item->{if(!item.session.getId().equals(sessionId)){//群发try{item.sendMessage(message);}catch(IOExceptione){e.printStackTrace();}}});}/**发生错误时调用@paramsessionsession@paramerrorerror/@OnErrorpublicvoidonError(Sessionsession,Throwableerror){System.out.println("----websocket-------有异常啦");error.printStackTrace();}/**减少在线人数/privatevoidsubOnlineCount(){WebSocketComponent.onlineCount--;}/**添加在线人数/privatevoidaddOnlineCount(){WebSocketComponent.onlineCount++;}/**当前在线人数@returnint/publicstaticsynchronizedintgetOnlineCount(){returnonlineCount;}/**发送信息@parammessagemessagethrowsIOException/publicvoidsendMessage(Stringmessage)throwsIOException{//获取session远程基本连接发送文本消息this.session.getBasicRemote().sendText(message);//this.session.getAsyncRemote().sendText(message);}@Overridepublicbooleanequals(Objecto){if(this==o){returntrue;}if(o==null||getClass()!=o.getClass()){returnfalse;}WebSocketComponentthat=(WebSocketComponent)o;returnObjects.equals(session,that.session);}@OverridepublicinthashCode(){returnObjects.hash(session);}}@ServerEndpoint注解标识当前WebSocket服务端endpoint地址,本文实际前端访问的ws地址为:ws://localhost:8080/websocket。至此,服务端工作完成。页面VUE端<template><el-cardv-loading="loading"element-loading-spinner="el-icon-loading":body-style="{padding:'5px',backgroundColor:'#eee'}"class="socket-box"shadow="hover"><divclass="socket-box__content":style="{height:(boxHeight-125)+'px'}"id="socket-content"><divv-if="hasMore"@click="loadMore"class="load-more"><span>加载更多</span></div><divv-elsestyle="width:100%;text-align:center;font-size:12px">没有更多了</div><divclass="item"v-for="minmessages":class="checkMe(m)?'sender':''"><divclass="slide"><divclass="avatar":style="{background:m.background}">{{m.name.substring(0,1)}}</div><divclass="meta"><divclass="name">{{m.name}}</div><divclass="date">{{m.createTime|datetime}}</div></div></div><p>{{m.content}}</p></div></div><divclass="socket-box__footer"><el-form@submit.native.prevent><el-form-item><el-inputtype="textarea"resize="none":rows="3":disabled="!connect":placeholder="connect?'输入内容...':'当前连接断开,请刷新重试!'":clearable="true"v-model="message"@keydown.native.enter="submitMsgForm"></el-input></el-form-item><el-form-item><el-button@click="sendMsg(message)":disabled="!connect"style="width:100%"type="primary"size="small">发送(Enter)</el-button></el-form-item></el-form></div></el-card></template><script>import{GET}from"@/api";exportdefault{name:"Chatroom",data(){return{messages:[],message:'',//boxHeight:document.documentElement.clientHeight-85,hasMore:true,pager:{pageNo:1,pageSize:10,total:0},loading:false,connect:false}},props:{boxHeight:{type:Number,required:true}},methods:{submitMsgForm(event){if(event.shiftKey){return;}event.preventDefault();this.sendMsg(this.message)},checkMe(message){letuser=localStorage.getItem("socketUser");if(user){user=JSON.parse(user);returnuser.uid===message.uid}else{returnfalse;}},initWebSocket:function(){this.websock=newWebSocket(`ws://localhost:8080/websocket`);this.websock.onopen=this.websocketonopen;this.websock.onerror=this.websocketonerror;this.websock.onmessage=this.websocketonmessage;this.websock.onclose=this.websocketclose;constthat=this;that.loading=true;GET({url:'/api/personal/web/message/socketData?pageNo=1',callback:res=>{if(res.code===200){that.messages=res.data.messages;that.hasMore=res.data.messages.length===that.pager.pageSize;that.$nextTick(function(){document.getElementById("socket-content").scroll({top:document.getElementById("socket-content").scrollHeight,left:0,behavior:'smooth'})})}that.loading=false}})},sendMsg(data){if(/^\s*$/.test(data)){this.message='';return;}//发送时传入JSON(UID,昵称,内容)constlocal=localStorage.getItem("socketUser");if(local){constl=JSON.parse(local);this.send(l,data)}else{//弹框this.$prompt('首次发表,请输入昵称','提示',{confirmButtonText:'确定',cancelButtonText:'取消',}).then(({value})=>{//随机生成UIDconstuid=this.randomVideoUuid(32,16);constform={uid:uid,name:value,background:`rgb(${Math.random()*255},${Math.random()*255},${Math.random()*255})`};localStorage.setItem("socketUser",JSON.stringify(form));this.send(form,data)}).catch(()=>{this.$message({type:'info',message:'取消输入'});});}},send(obj,data){obj.content=data;obj.createTime=newDate().getTime();this.websock.send(JSON.stringify(obj));this.message='';this.messages.push(obj);this.$nextTick(function(){document.getElementById("socket-content").scroll({top:document.getElementById("socket-content").scrollHeight,left:0,behavior:'smooth'})})},loadMore(){this.loading=true;constthat=this;if(this.hasMore){this.pager.pageNo+=1;GET({url:'/api/personal/web/message/socketData?pageNo='+this.pager.pageNo,callback:res=>{if(res.code===200){that.messages=[...res.data.messages,...that.messages];that.hasMore=res.data.messages.length>=that.pager.pageSize;}that.loading=false;}})}},websocketonopen:function(e){console.log("WebSocket连接成功",e);this.connect=true;},websocketonerror:function(e){console.log("WebSocket连接发生错误");this.connect=false;},websocketonmessage:function(e){constda=JSON.parse(e.data);this.messages.push(da);this.$nextTick(function(){document.getElementById("socket-content").scroll({top:document.getElementById("socket-content").scrollHeight,left:0,behavior:'smooth'})})},websocketclose:function(e){console.log("connectionclosed("+e.code+")");},randomVideoUuid(len,radix){letchars='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');letuuid=[];radix=radix||chars.length;if(len){for(leti=0;i<len;i++)uuid[i]=chars[0|Math.random()*radix];}else{letr;uuid[8]=uuid[13]=uuid[18]=uuid[23]='-';uuid[14]='4';for(leti=0;i<36;i++){if(!uuid[i]){r=0|Math.random()*16;uuid[i]=chars[(i===19)?(r&0x3)|0x8:r];}}}returnuuid.join('');},},mounted(){this.initWebSocket();}}</script>本段代码为简单的Vue实现的网页聊天室代码,其中@/api为自己简单封装的JS函数,用户初次进入页面时会生成一个随机UID保存到localStorage中,在mounted周期中初始化websocket连接。本聊天室最终效果地址:https://web.coralcloud.cn/blog/message
1.建基础包/文件夹2.application.propertis编写application.propertis基础配置和数据库连接3.index.ftl注:在index.ftl页面可以输入感叹号!,然后按tab键一键生成HTML代码4.IndexController.java5.启动服务启动服务,后再浏览器输入http://localhost:8080,是否能成功访问:
Linux离线安装Apache-2.41.系统环境信息系统版本:Linux2.6.32-696.el6.x86_64操作系统:Centos6.92.前置准备Apache-2.4编译安装依赖apr、apr-util、pcre,所以安装前需要先下载好四个离线安装包,安装包下载地址:apr-1.5.2apr-util-1.5.4pcre-8.42httpd-2.4.343.编译安装aprcd/home/softwaretar-zxvfapr-1.5.2.tar.gzcdapr-1.5.2./configure--prefix=/usr/local/apr-1.5.2make&&makeinstall4.编译安装apr-utilcd/home/softwaretar-zxvfapr-util-1.5.4.tar.gzcdapr-util-1.5.4./configure--prefix=/usr/local/apr-util-1.5.4--with-apr=/usr/local/apr-1.5.2make&&makeinstall5.编译安装pcrecd/home/softwaretar-zxvfpcre-8.42.tar.gzcdpcre-8.42./configure--prefix=/usr/local/pcre-8.42make&&makeinstall6.编译安装httpdcd/home/softwaretar-zxvfhttpd-2.4.34.tar.gzcdhttpd-2.4.34./configure--prefix=/usr/local/httpd-2.4.34--with-apr=/usr/local/apr-1.5.2--with-apr-util=/usr/local/apr-util-1.5.4--with-pcre=/usr/local/pcre-8.42make&&makeinstall7.配置httpd.confapache编译安装完成后,配置文件地址在/usr/local/apache-2.4.34/conf/httpd.conf修改启动端口为8080Listen80818.启动Apache创建软链接:ln-s/usr/local/apache-2.4.34/bin/apachectl/usr/bin/apachectl启动:/usr/bin/apachectl
一、FastDFS介绍1.1介绍FastDFS是一个C语言实现的开源轻量级分布式文件系统,支持Linux、FreeBSD、AID等Unix系统,解决了大数据存储和读写负载均衡等问题,适合存储4KB~500MB之间的小文件,如图片网站、短视频网站、文档、app下载站等,UC、京东、支付宝、迅雷、酷狗等都有使用,其中UC基于FastDFS向用户提供网盘、广告和应用下载的业务的存储服务FastDFS与MogileFS、HDFS、TFS等都不是系统级的分布式文件系统,而是应用级的分布式文件存储服务。1.2架构FastDFS服务有三个角色:跟踪服务器(TrackerServer)、存储服务器(storageserver)和客户端(client)TrackerServer:跟踪服务器,主要做调度工作,起到均衡的作用;负责管理所有的storageserver和group,每个storage在启动后会连接Tracker,告知自己所属group等信息,并保持周期性心跳,Tracker根据storage心跳信息,建立group--->[storageserverlist]的映射表;tracker管理的元数据很少,会直接存放在内存;tracker上的元信息都是由storage汇报的信息生成的,本身不需要持久化任何数据,tracker之间是对等关系,因此扩展tracker服务非常容易,之间增加tracker服务器即可,所有tracker都接受stroage心跳信息,生成元数据信息来提供读写服务(与其他Master-Slave架构的优势是没有单点,tracker也不会成为瓶颈,最终数据是和一个可用的StorageServer进行传输的)StorageServer:存储服务器,主要提供容量和备份服务;以group为单位,每个group内可以包含多台storageserver,数据互为备份,存储容量空间以group内容量最小的storage为准;建议group内的storageserver配置相同;以group为单位组织存储能够方便的进行应用隔离、负载均衡和副本数定制;缺点是group的容量受单机存储容量的限制,同时group内机器坏掉,数据恢复只能依赖group内其他机器重新同步(坏盘替换,重新挂载重启fdfs_storaged即可)1.3Group存储策略多个group之间的存储方式有3种策略:roundrobin(轮询)、loadbalance(选择最大剩余空间的组上传文件)、specifygroup(指定group上传)group中storage存储依赖本地文件系统,storage可配置多个数据存储目录,磁盘不做raid,直接分别挂载到多个目录,将这些目录配置为storage的数据目录即可storage接受写请求时,会根据配置好的规则,选择其中一个存储目录来存储文件;为避免单个目录下的文件过多,storage第一次启时,会在每个数据存储目录里创建2级子目录,每级256个,总共65536个,新写的文件会以hash的方式被路由到其中某个子目录下,然后将文件数据直接作为一个本地文件存储到该目录中1.4工作流程1.4.1上传FastDFS向使用者提供基本文件访问接口,比如upload、download、append、delete等,以客户端库的方式提供给用户使用。StorageServer会定期的向TrackerServer发送自己的存储信息。当TrackerServerCluster中的TrackerServer不止一个时,各个Tracker之间的关系是对等的,所以客户端上传时可以选择任意一个Tracker。当Tracker收到客户端上传文件的请求时,会为该文件分配一个可以存储文件的group,当选定了group后就要决定给客户端分配group中的哪一个storageserver。当分配好storageserver后,客户端向storage发送写文件请求,storage将会为文件分配一个数据存储目录。然后为文件分配一个fileid,最后根据以上的信息生成文件名存储文件。FastDFS上传时序图:1.4.2同步写文件时,客户端将文件写至group内一个storageserver即认为写文件成功,storageserver写完文件后,会由后台线程将文件同步至同group内其他的storageserver。每个storage写文件后,同时会写一份binlog,binlog里不包含文件数据,只包含文件名等元信息,这份binlog用于后台同步,storage会记录向group内其他storage同步的进度,以便重启后能接上次的进度继续同步;进度以时间戳的方式进行记录,所以最好能保证集群内所有server的时钟保持同步。storage的同步进度会作为元数据的一部分汇报到tracker上,tracke在选择读storage的时候会以同步进度作为参考。1.4.3下载客户端uploadfile成功后,会拿到一个storage生成的文件名,接下来客户端根据这个文件名即可访问到该文件。跟uploadfile一样,在downloadfile时客户端可以选择任意trackerserver。tracker发送download请求给某个tracker,必须带上文件名信息,tracke从文件名中解析出文件的group、大小、创建时间等信息,然后为该请求选择一个storage用来服务读请求。FastDFS下载时序图:二、FastDFS安装2.1下载安装libfastcommon下载libfastcommonwgethttps://github.com/happyfish100/libfastcommon/archive/V1.0.38.tar.gz解压tar-zxvfV1.0.38.tar.gzcdlibfastcommon-1.0.38编译安装./make.sh./make.shinstall2.2安装fastDFS下载wgethttps://github.com/happyfish100/fastdfs/archive/V5.10.tar.gz解压tar-zxvfV5.10.tar.gzcdfastdfs-5.10编译安装./make.sh./make.shinstallFastdfs的文件目录A、服务脚本:/etc/init.d/fdfs_storaged/etc/init.d/fdfs_trackerdB、配置文件模板:/etc/fdfs/client.conf.sample/etc/fdfs/storage.conf.sample/etc/fdfs/tracker.conf.sample2.3配置跟踪器(Tracker)进入/etc/fdfs,复制FastDFS跟踪器样例配置文件tracker.conf.sample,并重命名为tracker.conf。cd/etc/fdfscptracker.conf.sampletracker.confvimtracker.conf编辑tracker.conf,加粗的需要修改下,其它的默认即可。#配置文件是否不生效,false为生效disabled=false#提供服务的端口port=22122#Tracker数据和日志目录地址(根目录必须存在,子目录会自动创建)base_path=/home/data/fastdfs/trackerhttp.server_port=80创建tracker基础数据目录,即base_path对应的目录mkdir-p/home/data/fastdfs/tracker防火墙中打开跟踪端口(默认的22122)vim/etc/sysconfig/iptables最下面添加一行:-AINPUT-mstate--stateNEW-mtcp-ptcp--dport22122-jACCEPT重启iptables:serviceiptablesrestart启动Tracker初次成功启动,会在/home/data/fdfsdfs/tracker/(配置的base_path)下创建data、logs两个目录。可以用这种方式启动:/etc/init.d/fdfs_trackerdstartservicefdfs_trackerdstart查看FastDFSTracker是否已成功启动,22122端口正在被监听,则算是Tracker服务安装成功。netstat-unltp|grepfdfs关闭Tracker命令:servicefdfs_trackerdstop2.4配置存储(Storage)进入/etc/fdfs目录,复制FastDFS存储器样例配置文件storage.conf.sample,并重命名为storage.conf#cd/etc/fdfs#cpstorage.conf.samplestorage.conf#vimstorage.conf编辑storage.conf,加粗的需要修改,其它的默认即可。#配置文件是否不生效,false为生效disabled=false#指定此storageserver所在组(卷)group_name=group1#storageserver服务端口port=23000#心跳间隔时间,单位为秒(这里是指主动向trackerserver发送心跳)heart_beat_interval=30#Storage数据和日志目录地址(根目录必须存在,子目录会自动生成)base_path=/home/data/fastdfs/storage#存放文件时storageserver支持多个路径。这里配置存放文件的基路径数目,通常只配一个目录。store_path_count=1#逐一配置store_path_count个路径,索引号基于0。#如果不配置store_path0,那它就和base_path对应的路径一样。store_path0=/home/data/fastdfs/file#FastDFS存储文件时,采用了两级目录。这里配置存放文件的目录个数。#如果本参数只为N(如:256),那么storageserver在初次运行时,会在store_path下自动创建N*N个存放文件的子目录。subdir_count_per_path=256#tracker_server的列表,会主动连接tracker_server#有多个trackerserver时,每个trackerserver写一行tracker_server=192.168.1.161:22122#允许系统同步的时间段(默认是全天)。一般用于避免高峰同步产生一些问题而设定。sync_start_time=00:00sync_end_time=23:59#访问端口http.server_port=80创建Storage基础数据目录,对应base_path目录mkdir-p/home/data/fastdfs/storage这是配置的store_path0路径mkdir-p/home/data/fastdfs/file防火墙中打开存储器端口(默认的23000)vim/etc/sysconfig/iptables添加如下端口行:-AINPUT-mstate--stateNEW-mtcp-ptcp--dport23000-jACCEPT重启防火墙:serviceiptablesrestart启动Storage启动Storage前确保Tracker是启动的。初次启动成功,会在/home/data/fastdfs/storage目录下创建data、logs两个目录。可以用这种方式启动/etc/init.d/fdfs_storagedstartservicefdfs_storagedstart查看Storage和Tracker是否在通信:/usr/bin/fdfs_monitor/etc/fdfs/storage.conf
Centos安装ApacheHadoop2.7.7准备文件:hadoop-2.7.7.tar.gz一、安装JDK安装Hadoop之前需要保证JDK8成功安装java-version二、上传Hadoop压缩包上传成功后解压文件:tar-zxvfhadoop-2.7.7.tar.gz假设解压后的Hadoop目录为:/home/hadoop/hadoop-2.7.7注意配置HADOOP_HOME环境变量exportHADOOP_HOME=/home/hadoop/hadoop-2.7.7exportPATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin三、配置服务器免密登录$ssh-keygen-trsa-P''-f~/.ssh/id_rsa$cat~/.ssh/id_rsa.pub>>~/.ssh/authorized_keys$chmod0600~/.ssh/authorized_keys执行完成后:sshmaster命令则能够跳过输入密码阶段直接连接四、修改配置==配置文件所在位置:$HADOOP_HOME/etc/hadoop==core-size.xml<configuration><property><name>fs.defaultFS</name><value>hdfs://master:9000</value></property></configuration>hdfs-size.xml<configuration><property><name>dfs.replication</name><value>1</value></property></configuration>mapred-site.xml<configuration><property><name>mapreduce.framework.name</name><value>yarn</value></property><property><name>mapreduce.application.classpath</name><value>$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/*:$HADOOP_MAPRED_HOME/share/hadoop/mapreduce/lib/*</value></property></configuration>yarn-site.xml<configuration><property><name>yarn.nodemanager.aux-services</name><value>mapreduce_shuffle</value></property><property><name>yarn.nodemanager.env-whitelist</name><value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value></property></configuration>五、启动初始化HDFShdfsnamenode-format启动HDFSstart-dfs.sh启动YARNstart-yarn.sh启动成功后访问http://master:50070查看HDFS状态六、相关命令start-dfs.sh启动HDFS(namenode/datanode/SecondaryNamenode)stop-dfs.sh停止HDFSstart-yarn.sh启动Yarnstop-yarn.sh停止Yarnstart-all.sh启动HDFS和Yarnstop-all.sh停止HDFS和Yarn
ELK日志分析系统介绍1.系统概述本系统为业务日志分析监控系统,使用ELK+Beats实现对系统业务日志的收集、存储、分析,业务系统运行期间将相关日志输出到一个指定的文件夹/文件内,使用FileBeat组件实现对日志文件夹/文件的监听,可以直接将新增的数据发往设定好的Logstash中过滤,或直接发往ElasticSearch分类存储,当系统运行出现问题时,运维人员可以使用Kibana对存储在ES中的日志数据根据相关字段搜索查找,Kibana也支持对数据进行相应的可视化图表展现。2.系统实现描述2.1采集-filebeat对于日志数据收集使用Filebeat部署在业务服务器后台监听日志文件的方式。Filebeat运行环境没有任何依赖,后台运行占用内存资源极低,相比于Logstash可以忽略不计,不影响服务器正常的业务。Filebeat可以运行在MacOS、Windows、Linux等系统下。Filebeat监听指定的文件(可以使用通配符),一旦文件中有新的一行内容追加则会将这条数据发往配置好的output路径。Filebeat的output支持logstash、ElastciSearch、file、console等,一般的不需要复杂过滤的可以直接发往ES存储,多节点日志采集也可以经过Logstash汇总过滤后,再存储进ES。在Filebaet运行过程中,每个Prospector的状态信息都会保存在内存里。当Filebeat进行了重启后,会从注册表文件里恢复重启之前的状态信息,让FIlebeat继续从之前已知的位置开始进行数据读取。2.2解析-Logstash对于数据解析主要包括:(1)对汇总多节点后的日志进行区分(2)将不规则格式数据转换为规则数据(3)将不符合格式要求的数据过滤去除因为Filebeat只支持简单的数据解析,对于日志的解析过滤整体可以使用Logstash。Logstash内置许多解析格式:grok、date、ip、json...,支持对不规则的数据字符串进行规则化输出,也能够在数据传输过程中添加或删除某些指定字段。将采集到的日志数据经过logstash过滤转换后发往ES建立索引存储。因为logstash占用内存资源较大(默认1G),为不影响业务尽量不部署在业务服务器上。2.3存储-ElasticSearch日志数据存储使用ElasticSearch,由logstash将过滤完成后的规则化数据存入ES指定索引中。ES有自动发现功能,初期使用ElasticSearch的单节点集群模式,后续想要添加节点只需指定elasticsearch集群名称保持一致,就能自动加入集群,ES就会按照配置将索引分片到新加入的节点上。2.4展现-Kibana(1)ELK中Kibana专门为ES中的数据提供可视化展现的,支持搜索、汇总计算,图表展现等。(2)ElasticSearch也提供有RESTAPI,支持调用接口的方式访问操作索引数据。(3)使用插件进行数据异常监控报警功能实现,如系统日志出现异常报错则可配置发送邮件通知相关人员。(4)Kibana也支持对系统日志进行可视化监控展现,包括CPU、内存、硬盘等。3.系统可用性测试系统运行过程中,logstash宕机:Filebeat会记录发送不成功的数据,并尝试连接logstash,成功连接后会再次将数据发往logstash,下图为再次发送成功后的日志。系统运行过程中,Filebeat宕机:在Filebaet运行过程中,每个Prospector的状态信息都会保存在内存里。当Filebeat进行了宕机重启后,会从注册表文件里恢复重启之前的状态信息,让FIlebeat继续从之前已读取的位置开始往后进行数据读取。系统运行过程中,ES集群宕机::::hljs-centerLogstash日志::::::hljs-centerFilebeat日志:::logstash没有数据存储功能,ES集群宕机,logstash数据无法发送,Filebeat会记录未成功发送的数据,同时logstash定时尝试连接ES,直到连接成功,数据会再次发送。
1.@Component,@Service,@Controller,@Repository是spring注解,注解后可以被spring框架所扫描并注入到spring容器来进行管理2.@Component是通用注解,其他三个注解是这个注解的拓展,并且具有了特定的功能3.如果想使用自定义的组件注解,那么只要在你定义的新注解中加上@Component即可:4.@Repository注解在持久层中,具有将数据库操作抛出的原生异常翻译转化为spring的持久层异常的功能。5.@Controller层是spring-mvc的注解,具有将请求进行转发,重定向的功能。6.@Service层是业务逻辑层注解,这个注解只是标注该类处于业务逻辑层。7.用这些注解对应用进行分层之后,就能将请求处理,义务逻辑处理,数据库操作处理分离出来,为代码解耦,也方便了以后项目的维护和开发。
一、Sharding-jdbc简介Sharding-jdbc是开源的数据库操作中间件;定位为轻量级Java框架,在Java的JDBC层提供的额外服务。它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。官方文档地址:https://shardingsphere.apache.org/document/current/cn/overview/本文demo实现了分库分表功能。作者能力有限,如有错误,欢迎各位在评论中指出。不胜感激!二、项目结构首先创建一个一般的Springboot项目,项目采用三层架构,结构图如下:项目目录结构图POM.xml文件如下:<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.6.RELEASE</version><relativePath/><!--lookupparentfromrepository--></parent><groupId>com.macky</groupId><artifactId>spring-boot-shardingjdbc</artifactId><version>0.0.1-SNAPSHOT</version><name>spring-boot-shardingjdbc</name><description>Demoprojectforspring-boot-shardingjdbc</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!--Mybatis-Plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.1.1</version></dependency><!--shardingspherestart--><!--forspringboot--><dependency><groupId>io.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>3.1.0</version></dependency><!--forspringnamespace--><dependency><groupId>io.shardingsphere</groupId><artifactId>sharding-jdbc-spring-namespace</artifactId><version>3.1.0</version></dependency><!--shardingsphereend--><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>实体类以书本为例packagecom.macky.springbootshardingjdbc.entity;importcom.baomidou.mybatisplus.annotation.TableName;importcom.baomidou.mybatisplus.extension.activerecord.Model;importgroovy.transform.EqualsAndHashCode;importlombok.Data;importlombok.experimental.Accessors;/***@authorMacky*@TitleclassBook*@Description:书籍是实体类*@date2019/7/1315:23*/@Data@EqualsAndHashCode(callSuper=true)@Accessors(chain=true)@TableName("book")publicclassBookextendsModel<Book>{privateintid;privateStringname;privateintcount;}开放保存和查询两个接口,代码如下:packagecom.macky.springbootshardingjdbc.controller;importcom.macky.springbootshardingjdbc.entity.Book;importcom.macky.springbootshardingjdbc.service.BookService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.*;importjava.util.List;/***@authorMacky*@TitleclassBookController*@Description:TODO*@date2019/7/1220:53*/@RestControllerpublicclassBookController{@AutowiredBookServicebookService;@RequestMapping(value="/book",method=RequestMethod.GET)publicList<Book>getItems(){returnbookService.getBookList();}@RequestMapping(value="/book",method=RequestMethod.POST)publicBooleansaveItem(Bookbook){returnbookService.save(book);}}BookServiceImpl.javapackagecom.macky.springbootshardingjdbc.service.impl;importcom.baomidou.mybatisplus.core.toolkit.Wrappers;importcom.baomidou.mybatisplus.extension.service.impl.ServiceImpl;importcom.macky.springbootshardingjdbc.entity.Book;importcom.macky.springbootshardingjdbc.mapper.BookMapper;importcom.macky.springbootshardingjdbc.service.BookService;importorg.springframework.stereotype.Service;importjava.util.List;/***@authorMacky*@TitleclassBookServiceImpl*@Description:TODO*@date2019/7/1220:47*/@ServicepublicclassBookServiceImplextendsServiceImpl<BookMapper,Book>implementsBookService{@OverridepublicList<Book>getBookList(){returnbaseMapper.selectList(Wrappers.<Book>lambdaQuery());}@Overridepublicbooleansave(Bookbook){returnsuper.save(book);}}BookMapper.javapackagecom.macky.springbootshardingjdbc.mapper;importcom.baomidou.mybatisplus.core.mapper.BaseMapper;importcom.macky.springbootshardingjdbc.entity.Book;/***@authorMacky*@TitleclassBookMapper*@Description:TODO*@date2019/7/1220:46*/publicinterfaceBookMapperextendsBaseMapper<Book>{}创建数据库表,DDL语句如下:#创建数据库表数据CREATEDATABASEIFNOTEXISTS`db0`;USE`db0`;DROPTABLEIFEXISTS`book_0`;CREATETABLE`book_0`(`id`INT(11)NOTNULL,`name`VARCHAR(255)DEFAULTNULL,`count`INT(11)DEFAULTNULL,PRIMARYKEY(`id`))ENGINE=INNODBDEFAULTCHARSET=utf8mb4;DROPTABLEIFEXISTS`book_1`;CREATETABLE`book_1`(`id`INT(11)NOTNULL,`name`VARCHAR(255)DEFAULTNULL,`count`INT(11)DEFAULTNULL,PRIMARYKEY(`id`))ENGINE=INNODBDEFAULTCHARSET=utf8mb4;CREATEDATABASEIFNOTEXISTS`db1`;USE`db1`;DROPTABLEIFEXISTS`book_0`;CREATETABLE`book_0`(`id`INT(11)NOTNULL,`name`VARCHAR(255)DEFAULTNULL,`count`INT(11)DEFAULTNULL,PRIMARYKEY(`id`))ENGINE=INNODBDEFAULTCHARSET=utf8mb4;DROPTABLEIFEXISTS`book_1`;CREATETABLE`book_1`(`id`INT(11)NOTNULL,`name`VARCHAR(255)DEFAULTNULL,`count`INT(11)DEFAULTNULL,PRIMARYKEY(`id`))ENGINE=INNODBDEFAULTCHARSET=utf8mb4;CREATEDATABASEIFNOTEXISTS`db2`;USE`db2`;DROPTABLEIFEXISTS`book_0`;CREATETABLE`book_0`(`id`INT(11)NOTNULL,`name`VARCHAR(255)DEFAULTNULL,`count`INT(11)DEFAULTNULL,PRIMARYKEY(`id`))ENGINE=INNODBDEFAULTCHARSET=utf8mb4;DROPTABLEIFEXISTS`book_1`;CREATETABLE`book_1`(`id`INT(11)NOTNULL,`name`VARCHAR(255)DEFAULTNULL,`count`INT(11)DEFAULTNULL,PRIMARYKEY(`id`))ENGINE=INNODBDEFAULTCHARSET=utf8mb4;配置分库分表策略application.properties:#数据源db0,db1,db2sharding.jdbc.datasource.names=db0,db1,db2#第一个数据库sharding.jdbc.datasource.db0.type=com.zaxxer.hikari.HikariDataSourcesharding.jdbc.datasource.db0.driver-class-name=com.mysql.cj.jdbc.Driversharding.jdbc.datasource.db0.jdbc-url=jdbc:mysql://localhost:3306/db0?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTCsharding.jdbc.datasource.db0.username=rootsharding.jdbc.datasource.db0.password=Aa123456#第二个数据库sharding.jdbc.datasource.db1.type=com.zaxxer.hikari.HikariDataSourcesharding.jdbc.datasource.db1.driver-class-name=com.mysql.cj.jdbc.Driversharding.jdbc.datasource.db1.jdbc-url=jdbc:mysql://localhost:3306/db1?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTCsharding.jdbc.datasource.db1.username=rootsharding.jdbc.datasource.db1.password=Aa123456#第三个数据库sharding.jdbc.datasource.db2.type=com.zaxxer.hikari.HikariDataSourcesharding.jdbc.datasource.db2.driver-class-name=com.mysql.cj.jdbc.Driversharding.jdbc.datasource.db2.jdbc-url=jdbc:mysql://localhost:3306/db2?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTCsharding.jdbc.datasource.db2.username=rootsharding.jdbc.datasource.db2.password=Aa123456#水平拆分的数据库(表)配置分库+分表策略行表达式分片策略#分库策略sharding.jdbc.config.sharding.default-database-strategy.inline.sharding-column=idsharding.jdbc.config.sharding.default-database-strategy.inline.algorithm-expression=db$->{id%3}#分表策略其中book为逻辑表分表主要取决于id行sharding.jdbc.config.sharding.tables.book.actual-data-nodes=db$->{0..2}.book_$->{0..2}sharding.jdbc.config.sharding.tables.book.table-strategy.inline.sharding-column=count#分片算法表达式sharding.jdbc.config.sharding.tables.book.table-strategy.inline.algorithm-expression=book_$->{count%3}#主键UUID18位数如果是分布式还要进行一个设置防止主键重复#sharding.jdbc.config.sharding.tables.user.key-generator-column-name=id#打印执行的数据库以及语句sharding.jdbc.config.props..sql.show=truespring.main.allow-bean-definition-overriding=true#读写分离sharding.jdbc.datasource.dsmaster=接口测试使用postman示例:GET请求------>http://localhost:8080/bookPOST请求:------->http://localhost:8080/book?id=1&name=java编程思想&count=8demo的github地址:https://github.com/Macky-He/spring-boot--shardingsphere-examples如各位觉得有帮助的话,还请给个star鼓励鼓励博主,谢谢!三、总结分库分表实现按照官方文档做一个demo是第一步,如需深入还需要研究源码,研究架构,研究思想;此文仅作为入门demo搭建指南,如需深入理解,还请移步至官方文档。参考资料1.官方文档:https://shardingsphere.apache.org/document/current/cn/manual/sharding-jdbc/usage/sharding/
下载破解文件JetbrainsIdesCrack-3.4.jar将下载的文件复制到WebStorm安装文件夹下的bin文件夹下(在桌面上WebStorm快捷方式上右键【打开文件所在的位置】可直接进入)双击打开WebStorm进入激活页面,点选【Evaluateforfree】试用30天,进入应用界面在菜单【Help】->【EditcustomVMoptions..】点击打开配置文件.在配置文件最下方加入一行:-javaagent:D:\software\WebStorm2019.1.3\bin\JetbrainsIdesCrack-3.4.jar这里的文件路径具体指向到刚才复制的破解文件路径下在菜单【Help】->【Register...】点击打开激活页面,选择【licenseserver】激活方式,在下面输入框中填写:https://fls.jetbrains-agent.com点击【Activate】激活后,重启WebStorm生效.
- SpringBoot+Thymleaf项目初入(五) - 图片验证码
- SpringBoot+Thymleaf项目初入(四) - 用户登录页面优化
- SpringBoot+Thymleaf项目初入(三) - 用户登录
- SpringBoot+Thymleaf项目初入(二) - 配置基础页面访问
- SpringBoot+Thymleaf项目初入(一) - 基础项目搭建
- MyBatis之where关键字与<where>标签的区别
- 文件上传之@RequestParam与@RequestPart
- Spring注解之@Component
- SpringBoot框架之@Controller和@RestController的区别?
- Centos安装ApacheHadoop2.7.7