1. 系统架构演变概述

#mermaid-svg-F8dvnEDl6rEgSP97 .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-F8dvnEDl6rEgSP97 .label text{fill:#333}#mermaid-svg-F8dvnEDl6rEgSP97 .node rect,#mermaid-svg-F8dvnEDl6rEgSP97 .node circle,#mermaid-svg-F8dvnEDl6rEgSP97 .node ellipse,#mermaid-svg-F8dvnEDl6rEgSP97 .node polygon,#mermaid-svg-F8dvnEDl6rEgSP97 .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-F8dvnEDl6rEgSP97 .node .label{text-align:center;fill:#333}#mermaid-svg-F8dvnEDl6rEgSP97 .node.clickable{cursor:pointer}#mermaid-svg-F8dvnEDl6rEgSP97 .arrowheadPath{fill:#333}#mermaid-svg-F8dvnEDl6rEgSP97 .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-F8dvnEDl6rEgSP97 .flowchart-link{stroke:#333;fill:none}#mermaid-svg-F8dvnEDl6rEgSP97 .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-F8dvnEDl6rEgSP97 .edgeLabel rect{opacity:0.9}#mermaid-svg-F8dvnEDl6rEgSP97 .edgeLabel span{color:#333}#mermaid-svg-F8dvnEDl6rEgSP97 .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-F8dvnEDl6rEgSP97 .cluster text{fill:#333}#mermaid-svg-F8dvnEDl6rEgSP97 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-F8dvnEDl6rEgSP97 .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-F8dvnEDl6rEgSP97 text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-F8dvnEDl6rEgSP97 .actor-line{stroke:grey}#mermaid-svg-F8dvnEDl6rEgSP97 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-F8dvnEDl6rEgSP97 .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-F8dvnEDl6rEgSP97 #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-F8dvnEDl6rEgSP97 .sequenceNumber{fill:#fff}#mermaid-svg-F8dvnEDl6rEgSP97 #sequencenumber{fill:#333}#mermaid-svg-F8dvnEDl6rEgSP97 #crosshead path{fill:#333;stroke:#333}#mermaid-svg-F8dvnEDl6rEgSP97 .messageText{fill:#333;stroke:#333}#mermaid-svg-F8dvnEDl6rEgSP97 .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-F8dvnEDl6rEgSP97 .labelText,#mermaid-svg-F8dvnEDl6rEgSP97 .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-F8dvnEDl6rEgSP97 .loopText,#mermaid-svg-F8dvnEDl6rEgSP97 .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-F8dvnEDl6rEgSP97 .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-F8dvnEDl6rEgSP97 .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-F8dvnEDl6rEgSP97 .noteText,#mermaid-svg-F8dvnEDl6rEgSP97 .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-F8dvnEDl6rEgSP97 .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-F8dvnEDl6rEgSP97 .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-F8dvnEDl6rEgSP97 .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-F8dvnEDl6rEgSP97 .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-F8dvnEDl6rEgSP97 .section{stroke:none;opacity:0.2}#mermaid-svg-F8dvnEDl6rEgSP97 .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-F8dvnEDl6rEgSP97 .section2{fill:#fff400}#mermaid-svg-F8dvnEDl6rEgSP97 .section1,#mermaid-svg-F8dvnEDl6rEgSP97 .section3{fill:#fff;opacity:0.2}#mermaid-svg-F8dvnEDl6rEgSP97 .sectionTitle0{fill:#333}#mermaid-svg-F8dvnEDl6rEgSP97 .sectionTitle1{fill:#333}#mermaid-svg-F8dvnEDl6rEgSP97 .sectionTitle2{fill:#333}#mermaid-svg-F8dvnEDl6rEgSP97 .sectionTitle3{fill:#333}#mermaid-svg-F8dvnEDl6rEgSP97 .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-F8dvnEDl6rEgSP97 .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-F8dvnEDl6rEgSP97 .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-F8dvnEDl6rEgSP97 .grid path{stroke-width:0}#mermaid-svg-F8dvnEDl6rEgSP97 .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-F8dvnEDl6rEgSP97 .task{stroke-width:2}#mermaid-svg-F8dvnEDl6rEgSP97 .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-F8dvnEDl6rEgSP97 .taskText:not([font-size]){font-size:11px}#mermaid-svg-F8dvnEDl6rEgSP97 .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-F8dvnEDl6rEgSP97 .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-F8dvnEDl6rEgSP97 .task.clickable{cursor:pointer}#mermaid-svg-F8dvnEDl6rEgSP97 .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-F8dvnEDl6rEgSP97 .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-F8dvnEDl6rEgSP97 .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-F8dvnEDl6rEgSP97 .taskText0,#mermaid-svg-F8dvnEDl6rEgSP97 .taskText1,#mermaid-svg-F8dvnEDl6rEgSP97 .taskText2,#mermaid-svg-F8dvnEDl6rEgSP97 .taskText3{fill:#fff}#mermaid-svg-F8dvnEDl6rEgSP97 .task0,#mermaid-svg-F8dvnEDl6rEgSP97 .task1,#mermaid-svg-F8dvnEDl6rEgSP97 .task2,#mermaid-svg-F8dvnEDl6rEgSP97 .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-F8dvnEDl6rEgSP97 .taskTextOutside0,#mermaid-svg-F8dvnEDl6rEgSP97 .taskTextOutside2{fill:#000}#mermaid-svg-F8dvnEDl6rEgSP97 .taskTextOutside1,#mermaid-svg-F8dvnEDl6rEgSP97 .taskTextOutside3{fill:#000}#mermaid-svg-F8dvnEDl6rEgSP97 .active0,#mermaid-svg-F8dvnEDl6rEgSP97 .active1,#mermaid-svg-F8dvnEDl6rEgSP97 .active2,#mermaid-svg-F8dvnEDl6rEgSP97 .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-F8dvnEDl6rEgSP97 .activeText0,#mermaid-svg-F8dvnEDl6rEgSP97 .activeText1,#mermaid-svg-F8dvnEDl6rEgSP97 .activeText2,#mermaid-svg-F8dvnEDl6rEgSP97 .activeText3{fill:#000 !important}#mermaid-svg-F8dvnEDl6rEgSP97 .done0,#mermaid-svg-F8dvnEDl6rEgSP97 .done1,#mermaid-svg-F8dvnEDl6rEgSP97 .done2,#mermaid-svg-F8dvnEDl6rEgSP97 .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-F8dvnEDl6rEgSP97 .doneText0,#mermaid-svg-F8dvnEDl6rEgSP97 .doneText1,#mermaid-svg-F8dvnEDl6rEgSP97 .doneText2,#mermaid-svg-F8dvnEDl6rEgSP97 .doneText3{fill:#000 !important}#mermaid-svg-F8dvnEDl6rEgSP97 .crit0,#mermaid-svg-F8dvnEDl6rEgSP97 .crit1,#mermaid-svg-F8dvnEDl6rEgSP97 .crit2,#mermaid-svg-F8dvnEDl6rEgSP97 .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-F8dvnEDl6rEgSP97 .activeCrit0,#mermaid-svg-F8dvnEDl6rEgSP97 .activeCrit1,#mermaid-svg-F8dvnEDl6rEgSP97 .activeCrit2,#mermaid-svg-F8dvnEDl6rEgSP97 .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-F8dvnEDl6rEgSP97 .doneCrit0,#mermaid-svg-F8dvnEDl6rEgSP97 .doneCrit1,#mermaid-svg-F8dvnEDl6rEgSP97 .doneCrit2,#mermaid-svg-F8dvnEDl6rEgSP97 .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-F8dvnEDl6rEgSP97 .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-F8dvnEDl6rEgSP97 .milestoneText{font-style:italic}#mermaid-svg-F8dvnEDl6rEgSP97 .doneCritText0,#mermaid-svg-F8dvnEDl6rEgSP97 .doneCritText1,#mermaid-svg-F8dvnEDl6rEgSP97 .doneCritText2,#mermaid-svg-F8dvnEDl6rEgSP97 .doneCritText3{fill:#000 !important}#mermaid-svg-F8dvnEDl6rEgSP97 .activeCritText0,#mermaid-svg-F8dvnEDl6rEgSP97 .activeCritText1,#mermaid-svg-F8dvnEDl6rEgSP97 .activeCritText2,#mermaid-svg-F8dvnEDl6rEgSP97 .activeCritText3{fill:#000 !important}#mermaid-svg-F8dvnEDl6rEgSP97 .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-F8dvnEDl6rEgSP97 g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-F8dvnEDl6rEgSP97 g.classGroup text .title{font-weight:bolder}#mermaid-svg-F8dvnEDl6rEgSP97 g.clickable{cursor:pointer}#mermaid-svg-F8dvnEDl6rEgSP97 g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-F8dvnEDl6rEgSP97 g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-F8dvnEDl6rEgSP97 .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-F8dvnEDl6rEgSP97 .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-F8dvnEDl6rEgSP97 .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-F8dvnEDl6rEgSP97 .dashed-line{stroke-dasharray:3}#mermaid-svg-F8dvnEDl6rEgSP97 #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-F8dvnEDl6rEgSP97 #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-F8dvnEDl6rEgSP97 #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-F8dvnEDl6rEgSP97 #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-F8dvnEDl6rEgSP97 #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-F8dvnEDl6rEgSP97 #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-F8dvnEDl6rEgSP97 #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-F8dvnEDl6rEgSP97 #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-F8dvnEDl6rEgSP97 .commit-id,#mermaid-svg-F8dvnEDl6rEgSP97 .commit-msg,#mermaid-svg-F8dvnEDl6rEgSP97 .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-F8dvnEDl6rEgSP97 .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-F8dvnEDl6rEgSP97 .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-F8dvnEDl6rEgSP97 g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-F8dvnEDl6rEgSP97 g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-F8dvnEDl6rEgSP97 g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-F8dvnEDl6rEgSP97 g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-F8dvnEDl6rEgSP97 g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-F8dvnEDl6rEgSP97 g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-F8dvnEDl6rEgSP97 .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-F8dvnEDl6rEgSP97 .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-F8dvnEDl6rEgSP97 .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-F8dvnEDl6rEgSP97 .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-F8dvnEDl6rEgSP97 .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-F8dvnEDl6rEgSP97 .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-F8dvnEDl6rEgSP97 .edgeLabel text{fill:#333}#mermaid-svg-F8dvnEDl6rEgSP97 .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-F8dvnEDl6rEgSP97 .node circle.state-start{fill:black;stroke:black}#mermaid-svg-F8dvnEDl6rEgSP97 .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-F8dvnEDl6rEgSP97 #statediagram-barbEnd{fill:#9370db}#mermaid-svg-F8dvnEDl6rEgSP97 .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-F8dvnEDl6rEgSP97 .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-F8dvnEDl6rEgSP97 .statediagram-state .divider{stroke:#9370db}#mermaid-svg-F8dvnEDl6rEgSP97 .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-F8dvnEDl6rEgSP97 .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-F8dvnEDl6rEgSP97 .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-F8dvnEDl6rEgSP97 .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-F8dvnEDl6rEgSP97 .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-F8dvnEDl6rEgSP97 .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-F8dvnEDl6rEgSP97 .note-edge{stroke-dasharray:5}#mermaid-svg-F8dvnEDl6rEgSP97 .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-F8dvnEDl6rEgSP97 .error-icon{fill:#522}#mermaid-svg-F8dvnEDl6rEgSP97 .error-text{fill:#522;stroke:#522}#mermaid-svg-F8dvnEDl6rEgSP97 .edge-thickness-normal{stroke-width:2px}#mermaid-svg-F8dvnEDl6rEgSP97 .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-F8dvnEDl6rEgSP97 .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-F8dvnEDl6rEgSP97 .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-F8dvnEDl6rEgSP97 .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-F8dvnEDl6rEgSP97 .marker{fill:#333}#mermaid-svg-F8dvnEDl6rEgSP97 .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-F8dvnEDl6rEgSP97 {color: rgba(0, 0, 0, 0.75);font: ;}

集中式架构
垂直拆分
分布式服务
SOA面向服务架构
微服务架构

2. 微服务架构说明

SOA使用了ESB组件的面向服务架构:ESB自身实现复杂;应用服务粒度较大,所有服务之间的通信都经过ESB会降低通信速度;部署、测试ESB比较麻烦。

微服务架构:是一套使用小服务或者单一业务来开发单个应用的方式或途径。

微服务架构特点:

  • 单一职责
  • 服务粒度小
  • 面向服务(对外暴露REST api)
  • 服务之间相互独立

与使用ESB的SOA架构的区别:微服务架构没有使用ESB,有服务治理注册中心;业务粒度小。

3. 服务调用方式说明

  • RPC:基于socket,速度快,效率高;webservice、dubbo
  • HTTP:基于TCP,封装比较臃肿;对服务和调用方没有任何技术、语言的限定,自由灵活;RESTful,Spring Cloud

4. Spring RestTemplate示例工程导入

一般情况下有如下三种http客户端工具类包都可以方便的进行http服务调用:

  • httpClient
  • okHttp
  • JDK原生URLConnection

spring 提供了RestTemplate的工具类对上述的3种http客户端工具类进行了封装,可在spring项目中使用RestTemplate进行服务调用。

@RunWith(SpringRunner.class)
@SpringBootTest
public class RestTemplateTest {@Autowiredprivate RestTemplate restTemplate;@Testpublic void test(){String url = "http://localhost/user/8";//restTemplate可以对json格式字符串进行反序列化User user = restTemplate.getForObject(url, User.class);System.out.println(user);}
}

5. Spring Cloud概述

  • 整合的组件可以有很多组件;常见的组件有:eureka注册中心,Gateway网关,Ribbon负载均衡,Feign服务调用,Hystrix熔断器。在有需要的时候项目添加对于的启动器依赖即可。
  • 版本特征:以英文单词命名(伦敦地铁站名)

6. 创建微服务工程

需求:查询数据库中的用户数据并输出到浏览器

  • 父工程heima-springcloud:添加spring boot父坐标和管理其它组件的依赖
  • 用户服务工程user-service:整合mybatis查询数据库中用户数据;提供查询用户服务
  • 服务消费工程consumer-demo:利用查询用户服务获取用户数据并输出到浏览器

小结

            <!-- springCloud --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency>

通过 scope 的import可以继承 spring-cloud-dependencies 工程中的依赖

7. 搭建配置user-service工程

需求:可以访问http://localhost:9091/user/8输出用户数据

实现步骤:

  1. 添加启动器依赖(web、通用Mapper);
  2. 创建启动引导类和配置文件;
  3. 修改配置文件中的参数;
  4. 编写测试代码(UserMapper,UserService,UserController);
  5. 测试
  • 添加启动器依赖
    <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 通用Mapper启动器 --><dependency><groupId>tk.mybatis</groupId><artifactId>mapper-spring-boot-starter</artifactId></dependency><!-- mysql驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency></dependencies>
  • 编写配置文件
server:port: 9091
spring:datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/springcloudusername: rootpassword: rootmybatis:type-aliases-package: com.itheima.user.pojo

8. 搭建配置consumer-demo工程

目标:编写测试类使用restTemplate访问user-service的路径根据id查询用户

分析

需求:访问http://localhost:8080/consumer/8 使用RestTemplate获取http://localhost:9091/user/8的数据

实现步骤:

  1. 添加启动器依赖;
  2. 创建启动引导类(注册RestTemplate)和配置文件;
  3. 编写测试代码(ConsumerController中使用restTemplate访问服务获取数据)
  4. 测试
    <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
@SpringBootApplication
public class ConsumerApplication {public static void main(String[] args) {SpringApplication.run(ConsumerApplication.class, args);}@Beanpublic RestTemplate get(){return new RestTemplate();}
}
@RestController
@RequestMapping("/consumer")
public class ConsumerController {@Autowiredprivate RestTemplate restTemplate;@GetMapping("/{id}")public User get(@PathVariable long id){return restTemplate.getForObject("http://localhost:9091/user/"+id, User.class);}}
  • 服务管理
    如何自动注册和发现
    如何实现状态监管
    如何实现动态路由
  • 服务如何实现负载均衡
  • 服务如何解决容灾问题
  • 服务如何实现统一配置

上述的问题都可以通过Spring Cloud的各种组件解决。

9. Eureka注册中心说明

Eureka的主要功能是进行服务管理,定期检查服务状态,返回服务地址列表。

10. 搭建eureka-server工程

Eureka是服务注册中心,只做服务注册;自身并不提供服务也不消费服务。可以搭建web工程使用Eureka,可以使用Spring Boot方式搭建。

搭建步骤:

  1. 创建工程;
  2. 添加启动器依赖;
  3. 编写启动引导类(添加Eureka的服务注解)和配置文件;
  4. 修改配置文件(端口,应用名称…);
  5. 启动测试

小结

  • 启动器依赖
        <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency>
  • 配置文件
server:port: 10086
spring:application:name: eureka-server
eureka:client:service-url:# eureka 服务地址,如果是集群的话;需要指定其它集群eureka地址defaultZone: http://127.0.0.1:10086/eureka# 不注册自己register-with-eureka: false# 不拉取服务fetch-registry: false

11. 服务注册与发现

  • 服务注册:在服务提供工程user-service上添加Eureka客户端依赖;自动将服务注册到EurekaServer服务地址列表。

    • 添加依赖;
    • 改造启动引导类;添加开启Eureka客户端发现的注解;
    • 修改配置文件;设置Eureka 服务地址
  • 服务发现:在服务消费工程consumer-demo上添加Eureka客户端依赖;可以使用工具类根据服务名称获取对应的服务地址列表。
    • 添加依赖;
    • 改造启动引导类;添加开启Eureka客户端发现的注解;
    • 修改配置文件;设置Eureka 服务地址;
    • 改造处理器类ConsumerController,可以使用工具类DiscoveryClient根据服务名称获取对应服务地址列表。

添加依赖

      <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>

修改配置文件

eureka:client:service-url:defaultZone: http://127.0.0.1:10086/eureka

服务注册

@SpringBootApplication
@MapperScan("com.gogo.mapper")
@EnableDiscoveryClient
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class,args);}
}

服务发现

@RestController
@RequestMapping("/consumer")
public class ConsumerController {@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;@GetMapping("/{id}")public User get(@PathVariable long id){List<ServiceInstance> instances = discoveryClient.getInstances("user-service");ServiceInstance serviceInstance = instances.get(0);return restTemplate.getForObject("http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/user/"+id, User.class);}}

12. Eureka Server高可用配置

分析

Eureka Server是一个web应用,可以启动多个实例(配置不同端口)保证Eureka Server的高可用。

高可用配置:将Eureka Server作为一个服务注册到其它Eureka Server,这样多个Eureka Server之间就能够互相发现对方,同步服务,实现Eureka Server集群。

13. Eureka客户端与服务端配置

配置eureka客户端user-service的注册、续约等配置项,配置eureka客户端consumer-demo的获取服务间隔时间;了解失效剔除和自我保护

  • Eureka客户端工程

    • user-service 服务提供

      • 服务地址使用ip方式
      • 续约
    • consumer-demo 服务消费
      • 获取服务地址的频率
  • Eureka服务端工程 eureka-server
    • 失效剔除
    • 自我保护
  • user-service
eureka:client:service-url:defaultZone: http://127.0.0.1:10086/eurekainstance:# 更倾向使用ip地址,而不是host名prefer-ip-address: true# ip地址ip-address: 127.0.0.1# 续约间隔,默认30秒lease-renewal-interval-in-seconds: 5# 服务失效时间,默认90秒lease-expiration-duration-in-seconds: 5
  • consumer-demo
eureka:client:service-url:defaultZone: http://127.0.0.1:10086/eureka# 获取服务地址列表间隔时间,默认30秒registry-fetch-interval-seconds: 10
  • eureka-server
eureka:server:# 服务失效剔除时间间隔,默认60秒eviction-interval-timer-in-ms: 60000# 关闭自我保护模式(默认是打开的)enable-self-preservation: false

15. Ribbon负载均衡应用

分析

需求:可以使用RestTemplate访问http://user-service/user/8获取服务数据。

可以使用Ribbon负载均衡:在执行RestTemplate发送服务地址请求的时候,使用负载均衡拦截器拦截,根据服务名获取服务地址列表,使用Ribbon负载均衡算法从服务地址列表中选择一个服务地址,访问该地址获取服务数据。

实现步骤:

  1. 启动多个user-service实例(9091,9092);
  2. 修改RestTemplate实例化方法,添加负载均衡注解;
  3. 修改ConsumerController;
  4. 测试
@SpringBootApplication
public class ConsumerApplication {public static void main(String[] args) {SpringApplication.run(ConsumerApplication.class, args);}@Bean@LoadBalancedpublic RestTemplate get(){return new RestTemplate();}
}
@RestController
@RequestMapping("/consumer")
public class ConsumerController {@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate DiscoveryClient discoveryClient;@GetMapping("/{id}")public User get(@PathVariable long id){List<ServiceInstance> instances = discoveryClient.getInstances("user-service");ServiceInstance serviceInstance = instances.get(0);return restTemplate.getForObject("http://"+"user-service"+"/user/"+id, User.class);}}

小结

在实例化RestTemplate的时候使用@LoadBalanced,服务地址直接可以使用服务名。

16. 熔断器Hystrix简介

目标:了解熔断器Hystrix的作用

小结

Hystrix是一个延迟和容错库,用于隔离访问远程服务,防止出现级联失败。

17. 线程隔离&服务降级

Hystrix解决雪崩效应:

  • 线程隔离:用户请求不直接访问服务,而是使用线程池中空闲的线程访问服务,加速失败判断时间。

  • 服务降级:及时返回服务调用失败的结果,让线程不因为等待服务而阻塞。

  • consumer-demo中添加依赖

        <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency>
  • 开启熔断
@SpringCloudApplication
public class ConsumerApplication {public static void main(String[] args) {SpringApplication.run(ConsumerApplication.class, args);}@Bean@LoadBalancedpublic RestTemplate get(){return new RestTemplate();}
}
  • 降级逻辑
@RestController
@RequestMapping("/consumer")
@Slf4j
@DefaultProperties(defaultFallback = "defaultFall")
public class ConsumerController {@Autowiredprivate RestTemplate restTemplate;@GetMapping("/{id}")
/*    @HystrixCommand(fallbackMethod = "fall")*/@HystrixCommandpublic String get(@PathVariable long id){return restTemplate.getForObject("http://"+"user-service"+"/user/"+id, String.class);}public String fall(long id){log.error("查询{}失败",id);return "网络太差了";}public String defaultFall(){return "默认网络太差了";}}
  • 修改超时配置
hystrix:command:default:execution:isolation:thread:timeoutInMilliseconds: 2000

18. 服务熔断演示

@RestController
@RequestMapping("/consumer")
@Slf4j
@DefaultProperties(defaultFallback = "defaultFall")
public class ConsumerController {@Autowiredprivate RestTemplate restTemplate;@GetMapping("/{id}")
/*    @HystrixCommand(fallbackMethod = "fall")*/@HystrixCommandpublic String get(@PathVariable long id){if(id==1) throw new RuntimeException("不行的");return restTemplate.getForObject("http://"+"user-service"+"/user/"+id, String.class);}public String fall(long id){log.error("查询{}失败",id);return "网络太差了";}public String defaultFall(){return "默认网络太差了";}}
hystrix:command:default:execution:isolation:thread:timeoutInMilliseconds: 2000circuitBreaker:errorThresholdPercentage: 50 # 触发熔断错误比例阈值,默认值50%sleepWindowInMilliseconds: 10000 # 熔断后休眠时长,默认值5秒requestVolumeThreshold: 10 # 熔断触发最小请求次数,默认值是20

SpringCloud入门(一)相关推荐

  1. springcloud 入门 10 (eureka高可用)

    eureka高可用: 说白了,就是加一个实例作为原实例的备份,然后一起对外提供服务.这样可以保证在一台机器宕机的时候,整个系统不会死掉.保证其继续对外服务. eureka的集群化: 服务注册中心Eur ...

  2. SpringCloud入门之应用程序上下文服务(Spring Cloud Context)详解

    构建分布式系统非常复杂且容易出错.Spring Cloud为最常见的分布式系统模式提供了简单易用的编程模型,帮助开发人员构建弹性,可靠和协调的应用程序.Spring Cloud构建于Spring Bo ...

  3. SpringCloud入门 —— SSO 单点登录

    前言 本文适合初学者,如有不足或错误之处,还请大家在下方留言指正.(文章稍长,建议点赞收藏) 一.SSO单点登录是什么? 单点登录简介 单点登录SSO (Single Sign On) 是指在一个多系 ...

  4. 1、SpringCloud入门篇,综合概述

    SpringCloud 微服务概述 什么是微服务 目前的微服务并没有一个统一的标准,一般是以业务来划分 将传统的一站式应用,拆分成一个个的服务,彻底去耦合,一个微服务就是单功能业务,只做一件事. 与微 ...

  5. SpringCloud入门-狂神说

    工具:idea Spring官网:https://spring.io/ 详细了解博客连接:https://blog.csdn.net/weixin_43591980/article/details/1 ...

  6. SpringCloud学习一(回顾之前学的微服务知识点、springcloud入门概述、服务提供者和消费者)

    一.回顾之前,如何学习springcloud 回顾之前的知识? JavaSE 数据库 前端 Servlet Http Mybatis Spring SpringMVC SpringBoot Dubbo ...

  7. SpringCloud入门 - 分布式事务【概念、常见框架选择 - tx-lcn】

    分布式事务简介: 事务: 指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行. 本地事务:  SqlSessionfactory   --> 一个数据库范围类事务管理. 分 ...

  8. SpringCloud 入门教程(五): Ribbon实现客户端的负载均衡

    接上节,假如我们的Hello world服务的访问量剧增,用一个服务已经无法承载, 我们可以把Hello World服务做成一个集群. 很简单,我们只需要复制Hello world服务,同时将原来的端 ...

  9. SpringCloud入门实例

    SpringCloud微服务 概述 ​ Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心.消息总线 ...

  10. Day2:SpringCloud入门学习——传智播客学习笔记【微服务电商】

    SpringCloud 0.学习目标 ·了解系统架构的演变 ·了解RPC与Http的区别 ·掌握HttpClient的简单使用 ·知道什么是SpringCloud ·独立搭建Eureka注册中心 ·独 ...

最新文章

  1. 用C#.NET调用Java开发的WebService传递int,double问题,出现java无法获
  2. eclipse maven创建web项目
  3. 可重复使用的MicroProfile Health探针
  4. 将MongoDB与Morphia结合使用
  5. 搜索不包含关键词_亚马逊listing关键词优化
  6. 这是一条“神奇”的评论
  7. Python编辑器--Ulipad
  8. 机器人学基础(一):空间描述与坐标变换
  9. [C#] TestHttpPost:测试Http的POST方法的小工具
  10. java 画正弦函数曲线_java打印正弦曲线示例
  11. 水果店开业怎样宣传自己的水果店,新开水果店怎么发朋友圈宣传
  12. python爬虫如何防止IP屏蔽
  13. win7计算机无法连接投影仪,手把手操作win7系统无法连接投影仪的修复教程
  14. 2017字节跳动前端工程师秋招笔试试题解析
  15. Android中MaterialSearchView(搜索框)的简单实用
  16. 快速了解矢量量化Vector-Quantized(VQ)及相应代码
  17. android修改输出分辨率,编译Android8.1修改默认分辨率和屏幕密度
  18. fs.mkdir创建目录报错
  19. 篮球大数据公司贝泰科技完成A轮融资 投后估值8500万
  20. qtp 连接mysql_qtp 怎样连接mysql数据库操作_MySQL

热门文章

  1. 04-树7 二叉搜索树的操作集 (30 分)
  2. Web For Pentester -- File Upload
  3. 路由器架设虚拟服务器让外网访问到本地网站
  4. spring中注解的通俗解释
  5. HTML 页面源代码布局介绍
  6. Synergy如果timeout的可能原因
  7. 易语言动画框和动画物体通过代码载入外部图片数据不显示!
  8. ANTLR和StringTemplate
  9. linux下elasticsearch的安装
  10. skimage库需要依赖 numpy+mkl 和scipy