架构说明
存在的问题:
- 代码耦合,开发维护困难
- 无法针对不同模块进行针对性优化
- 无法水平扩展
- 单点容错率低,并发能力差
优点:
- 系统拆分实现了流量分担,解决了并发问题
- 可以针对不同模块进行优化
- 方便水平扩展,负载均衡,容错率提高
缺点:
- 系统间相互独立,会有很多重复开发工作,影响开发效率
优点:
- 将基础服务进行了抽取,系统间相互调用,提高了代码复用和开发效率
缺点:
-
系统间耦合度变高,调用关系错综复杂,难以维护
-
以前出现了什么问题? -
服务越来越多,需要管理每个服务的地址
-
调用关系错综复杂,难以理清依赖关系
-
服务过多,服务状态难以管理,无法根据服务情况动态管理
服务治理要做什么?
- 服务注册中心,实现服务自动注册和发现,无需人为记录服务地址
- 服务自动订阅,服务列表自动推送,服务调用透明化,无需关心依赖关系
- 动态监控服务状态监控报告,人为控制服务状态
缺点:
- 服务间会有依赖关系,一旦某个环节出错会影响较大
- 服务关系复杂,运维、测试部署困难,不符合DevOps思想
微服务
前面说的SOA,英文翻译过来是面向服务。微服务,似乎也是服务,都是对系统进行拆分。因此两者非常容易混淆,但其实却有一些差别:
微服务的特点:
- 单一职责:微服务中每一个服务都对应唯一的业务能力,做到单一职责
- 微:微服务的服务拆分粒度很小,例如一个用户管理就可以作为一个服务。每个服务虽小,但“五脏俱全”。
- 面向服务:面向服务是说每个服务都要对外暴露Rest风格服务接口API。并不关心服务的技术实现,做到与平台和语言无关,也不限定用什么技术实现,只要提供Rest的接口即可。
- 自治:自治是说服务间互相独立,互不干扰
- 团队独立:每个服务都是一个独立的开发团队,人数不能过多。
- 技术独立:因为是面向服务,提供Rest接口,使用什么技术没有别人干涉
- 前后端分离:采用前后端分离开发,提供统一Rest接口,后端不用再为PC、移动段开发不同接口
- 数据库分离:每个服务都使用自己的数据源
- 部署独立,服务间虽然有调用,但要做到服务重启不影响其它服务。有利于持续集成和持续交付。每个服务都是独立的组件,可复用,可替换,降低耦合,易维护
架构的演变 传统架构–>水平拆分–>垂直拆分(最早的分布式)–>soa(dubbo)–>微服务(springCloud)
spring公司的核心产品,如图
我们也可以到它的官网去看,百度我就不贴图了,spring全家桶😀
项目启动 搭建 Eureka注册中心
为什么要搭建Eureka注册中心,Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。
Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。Eureka Server本身也是一个服务,默认情况下会自动注册到Eureka注册中心。,去官方可以看下对应版本号
pringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。
这里可以使用IDEA的spring的 initalizr搭建
不过也可以使用官网的快速开始来,搭建,我这里就用官网的开始搭建
进入到这里,点击start.spring.io
如图所示,最右边呢可以换背景
添加依赖这里我稍微改了下,这里搭建 注册中心服务端,所以只需要一个 Eureka Server
选错了,点这里可以删除掉
键盘输入Ctrl + 回车,下载下来之后,解压,导入进去
只需要找到刚刚解压的项目的pom.xml,点击ok
默认下一步,就好了,初始了一个springboot的项目,springboot的一个启动依赖,就有一堆的jar包,springboot内置了tomcat,里面有hikari连接池,Hikari是一款非常强大,高效,并且号称“史上最快连接池”。并且在springboot2.0之后,采用的默认数据库连接池就是Hikari。不需要引入依赖,已经在SpringBoot中包含了。
把src目录删掉,因为这里要用到maven的拆分聚合思想,每一个模块就可以独立启动
然后用到Git ,没集成的话,不过你要去下载Git,可以按照下图就可以了
这里说明下等下好打开控制台用
初始化
Git init初始化
就可以看到这个项目交给Git来管理了
点击Git commit
这两项也是检查各种问题的
如果没有输入用户名的话就输入用户名,邮箱啥的
初始工作完成了就完成了
创建eureka子模块
eureka是一个注册中心,服务管理
Eure可以参考这里
为什么需要Eureka参考
这里是说,要不要交给Git来管理,点击Yes是就完事了
创建了Eureka 因为注册中心,不知道 他自己是注册中心
把父工程的中的注册中心搬到子模块中,父工程不需要那个依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
然后在子模块的src目录下创建SpringBoot的启动类
Springboot默认集成 tomcat<>/font
新建一个application.properties文件,解决注册中心启动失败问题
spring.application.name=eureka
# eureka 官方的端口号
server.port=8761
############### 启动报错就是 因为 下面那两个 #########################
# 获取注册信息 因为本身就是 注册中心 所以本身就不需要获取注册信息 这里默认为 true
eureka.client.fetch-registry=false
# 注册到 eureka注册中心去,本身就是注册中心 不需要去注册
eureka.client.register-with-eureka=false
启动类加上@EnableEurekaServer
http://localhost:8761/地址栏输入,启动成功了
这里可以改造下boot启动类,这是一种固定的写法
private static final Logger LOG = LoggerFactory.getLogger(EurekaApplication.class);
public static void main(String[] args) {
SpringApplication app = new SpringApplication(EurekaApplication.class);
Environment env = app.run(args).getEnvironment();
LOG.info("启动成功!!");
LOG.info("Eureka地址: \thttp://127.0.0.1:{}", env.getProperty("server.port"));
}
在新建一个,logback.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 修改一下路径 value 是日志输出的路径 不要使用绝对路径,不是每个电脑又D盘F盘什么的 日志输出根据你的项目路径输出的-->
<property name="PATH" value="/log/adger/eureka"></property>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!--打印 年月日 时分秒%d{yyyy-MM-dd HH:mm:ss.SSS} 高亮显示 %highlight(%-5level) 控制台颜色 %blue(%-50logger{50}:%-4line) 日志信息 %msg%n</Pattern>-->
<Pattern>%d{ss.SSS} %highlight(%-5level) %blue(%-30logger{30}:%-4line) %msg%n</Pattern>
</encoder>
</appender>
<!-- 输出级别 TRACE_FILE 输出到文件里面去 -->
<appender name="TRACE_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${PATH}/trace.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${PATH}/trace.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<layout>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %-50logger{50}:%-4line %green(%-8X{UUID}) %msg%n</pattern>
</layout>
</appender>
<!-- 错误级别 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${PATH}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${PATH}/error.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<layout>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %-50logger{50}:%-4line %green(%-8X{UUID}) %msg%n</pattern>
</layout>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<root level="ERROR">
<appender-ref ref="ERROR_FILE" />
</root>
<root level="TRACE">
<appender-ref ref="TRACE_FILE" />
</root>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>
启动,就可以点击地址了
日志输出
这篇文章也是,断断续续的写的😂