springcloud2020
整理知识
串一下自己之前的东西
这个阶段该如何学
在学习新知识的同时不忘回顾自己以及拥有的知识
我自己的东西
- javaSE
- 数据库
- 前端知识
- Servlet
- springboot
- Mybatis
- spring
- Maven
- Ajax
- dubbo+zookeeper
我差了的东西
- Http
标准的变化
我们在之前以学过了ssm
我们的开发核心在哪里
javaEE标准
spring javaEE开发标准
spring几乎连接着我们开发中的一切,他就像一个中央集成一样
但是慢慢的我们发现,他真的轻量吗?
- 随着开发量不断增多的配合内容
让他变得不再轻量,于是乎新的解决方案诞生了
javaEE新标准
springboot javaEE开发新的标准
他简化了繁琐的配置,自动化的帮助我们干了很多的配置上需要重复干的事情, 给了我们一套默认的解决方案,我们可以把boot理解成一个 spring的plus版,他集成了很多的启动器,从而让springboot逐渐取代了 ssm,springboot慢慢的变成了javaEE最好的解决方案,让无数企业喜爱
不管是新标准还是旧标准,他的特点是统一的:约定大于配置
最开始
我们现在开发的程序 all in one 的形式,所有的模块全在一个jar或者war包下
演进
那么随着架构的演进我们逐渐把功能拆分出来,代码并没有什么变化
但是一旦并发量高起来,这样的架构,我们的机器无法让业务正常实行了
现在
解决方法应运而生,微服务架构
把功能拆分多个设备上去,来解决性能上导致业务无法正常运行的问题
微服务四大核心问题:
- 服务很多,用户如何访问,注册中心
- 服务中如何通信 : rpc
- 这么多服务,服务治理?
- 服务挂了怎么办?
对于这些问题,spring cloud是个生态
用来解决这四个问题的
- Spring cloud netfix 一站式解决方案
api网关,zuul组件
Feign --HttpClinet ----Http通信方式
服务注册发现:Eureka
熔断机制: Hystrix
。。。。 - Apache Dubbo zookeeper 半自动,需要整合别人的
API 没有,找第三方组件,或者自己实现
Dubbo 通信,高性能 rpc框架
服务注册发现:zookeeper
熔断机制并没有:借助 Hystrix - Spring Cloud Alibaba 最新的一站式解决方案!
新概念:服务网格!server mesh
概念都是一样的:
- API
- http rpc
- 注册与发现
- 熔断机制
为什么会出现这个情况,因为:网络不可靠!
微服务
- 就目前而言微服务,业界没有统一标准的定义
- 微服务架构是一种架构模式,或者是一种架构风格他提倡单一应用程序划分一组小服务,每个服务运行在自己独立的进程内,服务之间,互相协调,互相配置,为用户提倡最终的价值,体现最终价值,服务之间采用轻量级的通信机制互相沟通,每个服务围绕具体的业务构建,并且能够被独立的部署在生产环境中,另外,尽量避免统一的,集中式管理的服务管理机制,对具体的一个服务而言,根据上下文,选择合适的语言,工具,对齐构建,可以有一个非常轻量的集中式管理来协调业务,可以使用不同的语言编写,也可以用不同的数据储存
我们从技术维度理解一下
就是微服务的作用就是将传统的一个项目解决业务(一站式应用)根据业务拆分成一个一个的服务,去彻底的去耦合,每个微服务提供单个业务的功能服务,一个服务做一个事情,从技术角度来说就是一个小而独立的处理过程,类的进程的概念,能够自行单独启动或销毁,拥有自己独立的数据库
微服务与微服务架构
微服务
强调的是服务的大小 ,他关注的是一个点,是具体解决某一个问题提供落地对服务的应用,就是idea中一个个微服务的工程或者moudel
idea工具里面使用maven建立的一个个独立的小moudle,他具体是使用springboot开发的一个个小模块,专业的事情交给专业的模版来做,一个模块做着一件事情
强调的是一个个的个体,每个个体完成一个具体的任务或者功能!
微服务架构
一钟新的架构形式,Martin Fowler
2014推出
- 微服务架构是一种架构模式,或者是一种架构风格他提倡单一应用程序划分一组小服务,每个服务运行在自己独立的进程内,服务之间,互相协调,互相配置,为用户提倡最终的价值,体现最终价值,服务之间采用轻量级的通信机制互相沟通,每个服务围绕具体的业务构建,并且能够被独立的部署在生产环境中,另外,尽量避免统一的,集中式管理的服务管理机制,对具体的一个服务而言,根据上下文,选择合适的语言,工具,对齐构建,可以有一个非常轻量的集中式管理来协调业务,可以使用不同的语言编写,也可以用不同的数据储存
微服务的有缺点
优点
- 单一职责原则
- 每个服务足够内聚,足够小,代码容易理解,这个能聚焦一个指定的业务功能和业务需求
- 开发简单,开发效率提高,一个服务可能就是转义的只干一件事情
- 微服务能够被小团队单独开发,这个小团队是2~5的开发人员组成
- 微服务是松耦合的,是具有功能意义的服务,无论是在开发阶段或者部署阶段都是独立的
- 微服务能使用不同的预言开发
- 易于是第三方集成,微服务允许容易且灵活的方式集成自动部署,通过持续集成工具,如jenkins,hudson,bamboo
- 微服务易于被一个开发人员理解,修改和维护,这样小团队能够更加关注自己的工作成果。无需通过合作才能体现价值
- 微服务允许你利用融合最新技术
- 微服务只是业务逻辑的代码,不会喝html,css或其他的界面混合
- 每个微服务都有自己的储存能力,可以有自己的数据库,也可以有统一数据库
缺点:
- 开发人员要处理分布式系统的复杂性
- 多服务运维难度,随着服务的增加,运维压力也在增大
- 系统部署依赖
- 服务间通信成本
- 数据一致性
- 系统集成测试
- 性能监控
微服务技术栈
微服务技术条目 |
落地技术 |
服务开发 |
SpringBoot,Spring,SpringMVC |
服务配置与管理 |
netflix公司的archaius和阿里的diamond等 |
服务注册与发现 |
eureka,consul,zookeeper |
服务调用 |
rest,rpc,grpc |
服务熔断器 |
Hystrix,Envoy等 |
负载均衡 |
RIbbon,nginx等 |
服务接口调用(服务端调用服务的简化工具) |
Feign等 |
消息队列 |
kafka,rabbitMQ,ActiveMQ |
服务配置中心管理 |
SpringCloudconfig,chef等 |
服务路由 |
Zuul等 |
服务监控 |
zabbix,Nagios,M ertrics,Specatator |
全链路追踪 |
Zipkin,Brave,Dapper |
服务部署 |
DOCKER,openStack,kubernetes |
数据操作开发包 |
Springcloud Stream(封装与rides,rabbit,kafka等发送接收消息) |
事件消息总线 |
springcloud Bus |
为什么我们要选择SpringCloud作为微服务架构呢
1、选型依据
- 整体解决方案和框架成熟度
- 社区热度
- 可维护性
- 学习曲线
2、当前各大公司微服务架构是那些
- 阿里:dubbo+hfs
- 京东:jsf
- 新浪:Motan
- 当当: bubbox
功能和服务框架 |
Netflix/springCloud |
Motan |
grpc |
thrift |
Dubbo/dubbox |
功能定位 |
完整的微服务框架 |
rpc框架但是整合了zk或者consul可以实现集群环境和基本的服务注册发现 |
rpc框架 |
rpc框架 |
服务框架 |
支持rest |
支持,ribbon支持多种可插拔序列化选择 |
否 |
否 |
否 |
否 |
支持rpc |
否(但是可以和dubbo兼容) |
是 |
是 |
是 |
是 |
支持多语言 |
支持(rest形式) |
否 |
是 |
是 |
否 |
负载均衡 |
支持(服务端zuul+客户端ribbon),zuul服务,动态路由,云端负载均衡,eureka针对中间层服务器 |
支持(客户端) |
否 |
否 |
是(客户端) |
配置服务 |
netfix archaius spring cloud config Server集中配置 |
是(zookeeper提供) |
否 |
否 |
否 |
服务调用链监 |
支持,zuul,zuul提供边缘服务,api网关 |
否 |
否 |
否 |
否 |
高可用/容错 |
支持,服务端hystrix+ribbon |
支持(客户端) |
否 |
否 |
支持(客户端) |
典型应用案例 |
Netflix |
sina |
|||
社区活跃度 |
高 |
一般 |
高 |
一般 |
2017才开始重新维护,之前中断了五年 |
学习难度 |
中 |
低 |
高 |
高 |
低 |
文档丰富程度 |
高 |
一般 |
一般 |
一般 |
高 |
其他 |
SpringCloud bus为我们的应用带来更多的管理端点 |
支持降级 |
netflix内部在开发集成grpc |
idl定义 |
实践的公司比较多 |
springcloud入门概述
springcloud是什么?
springcloud基于springboot提供了一套微服务解决方案,包括服务注册,发现,配置中心,全链路监控
服务网管,负载均衡,熔断器等组件,除了基于netflix的开源组件做高度抽象封装之外,还有一些选型中立得1开源组件。
springcloud利用springboot的开发便利性,巧妙的简化了分布式系统基础设施额开发,springcloud为开发人员提供了快速构建分布式系统的一些工具,包括配置管理,服务发现,断路器,路由,微代理,事件总线,全局锁,决策竞选,分布式会话等等,他们都可以用springboot的开发风格做到一键启动部署
springboot并没有重复造轮子,他只是将目前各家公司开发的比较成熟经得起实际考研的 服务框架组合起来,通过springboot风格进行封装,屏蔽掉了复杂的配置,和实现原理,最终给开发者留出一套简单易懂,易部署,和易维护的分布式系统开发工具包
springcloud是分布式微服务架构下的一站式解决方案,是各个微服务架构落地技术的集合体,俗称微服务全家桶
springboot和springcloud的关系
- springboot专注于快速方便的开发单个个体微服务
- springcloud是关注全局微服务协调治框架,他将springboot开发的一个个单体微服务,整合并管理起来,为各个微服务之间提供了配置管理,服务发现,断路器,路由,事件总线全局锁,决策竞选,分布式会话等等集成服务
- springboot可以离开springcloud独立使用,开发项目,但是springcloud离不开springboot,属于依赖关系
- springboot专注于快速方便的开发单个个体微服务,springcloud关注全局的服务治理框架
Dubbo和springcloud技术选型
分布式+服务治理Dubbo
目前成熟的互联网架构:应用服务化拆分+消息中间件
Dubbo和springcloud对比
dubbo应为停更了之后,社区并不活跃,垂死状态,未来未知
springcloud的社区十分活跃,正值壮年,
对比图:
最大区别:springcloud抛弃了Dubbo的rpc通信,采用基于http的rest方式
严格来说,两种方式各有优劣,从一定程度上,后者牺牲了服务调用的性能,但是也比避免了原生rpc带来的问题,rest相比rpc更加的灵活,服务提供方和调用方的依赖只靠一个七月,不存在在吗级别的强依赖,这就是强调快速烟花的微服务环境下,显得更加合适
品牌机和组装机的区别
springcloud(品牌机):
很明显的一点就是,springcloud的功能比dubbo强大的太多,覆盖面更广,而且作为spring的明星项目,他也能够和其他的spring项目完美融合。
dubbo(组装机):
使用dubbo构建微服务架构就像组装电脑,各环节,我们的选择自由度非常高,但是最终结果可能是就是一个内存条不点亮了,总是不让人那么放心,但是如果是一个高手,那这些都不是问题, springcloud就像品牌机,在spring source的整合下,做了大量的兼容性测试,保证了机器拥有更高的稳定性,但是如果要在使用非原装组件外的东西,就需要对其基础足够了解,
社区支持和更新力度
最重要的是,dubbo停止了5年狗熊,虽然17年重启了,对于技术发展的需求,更需要爱发展着自行拓展升级,比如dubbox,对于这很多想要采纳微服务的中小软件组织,显然是不太合适的,中小公司没有那么强大的技术去修改dubbo的源码+周边的一整套解决方案。并不是每个公司都有阿里的大牛+真实线上生产环境测试过
总结
曾风靡国内的rpc框架Dubbo在重启维护后,让很多用户为之雀跃,但是同时也要有质疑的声音,发展迅速的时代,dubbo能否跟上?dubbo和springcloud的差异 ?是否会有相关的举措保证dubbo的后续更新频率
dubbo是一个专注rpc框架,springcloud的目标是微服务架构下的一站式解决方案
设计模式+微服务拆分思想:不一定善于表达的技术人才,你可以领导他,软实力是职场关键的一点,你可能技术没有人才好,但是你的设计思维,架构理解和表达能力让你可以成为只会技术人才的团队leader,
springcloud下载
springcloud的不同版本
以伦敦地铁站和字符开头来命名
接下来是需要知道的几个文档
springcloud的中文文档:https://www.springcloud.cc/spring-cloud-dalston.html
社区官网:http://docs.springcloud.cn/
以上的理论内容是和代码挂钩的,很多面试中淡资也是很重要的东西
上手实战咯
- 我们使用一个支付模块做一个微服务通用案例,用rest风格
- 回忆ssm所学的知识
- maven分包分模块的架构复习
一个父工程带着多个子模块
动手!
springcloud的大版本说明
springboot |
springcloud |
关系 |
1.2.x |
天使版angel |
兼容boot1.2.x |
1.3.x |
brixton版本 |
兼容spring1.3,也兼容1.4 |
1.4.x |
camden版本 |
兼容spring1.4,也兼容1.5 |
1.5.x |
dalston版本 |
兼容spring1.5,不兼容2.0.x |
1.5.x |
edgware |
兼容spring1.5,不兼容2.0 |
2.0.x |
finchley |
兼容spring2.0,不兼容1.5 |
2.1.x |
greenwich |
到了2020我们发现技术一代一代的换,有的技术慢慢的停止更新维护,又会有新的更全面的解决方案跟上,时代快速发展
cloud项目搭建
我们采用的是用maven聚合项目作为父项目
在里面编写子模块,主要是可以解决一个问题
就是子模块依赖版本的统一管理
这里呢我们就要用到dependencyManagement+properties来控制版本
下图就是关于dependencyManagement的一些知识复习
父项目pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="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.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.hyc.springcloud</groupId> <artifactId>cloud2020</artifactId> <version>1.0-SNAPSHOT</version> <modules> <module>cloud-provider-payment8001</module> </modules> <packaging>pom</packaging> <!-- 统一管理jar包版本 --> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <junit.version>4.12</junit.version> <log4j.version>1.2.17</log4j.version> <lombok.version>1.16.18</lombok.version> <mysql.version>8.0.11</mysql.version> <druid.version>1.1.16</druid.version> <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version> </properties> <!-- 子模块继承之后,提供作用:锁定版本+子modlue不用写groupId和version --> <dependencyManagement> <dependencies> <!--spring boot 2.2.2--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.2.2.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <!--spring cloud Hoxton.SR1--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR1</version> <type>pom</type> <scope>import</scope> </dependency> <!--spring cloud alibaba 2.1.0.RELEASE--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.1.0.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>${druid.version}</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>${mybatis.spring.boot.version}</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> <optional>true</optional> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> <addResources>true</addResources> </configuration> </plugin> </plugins> </build> </project>
搞定这边之后,我们就可以去编写子模块了
支付模块,服务提供者
建cloud-provider-payment8001
在springboot的学习中我们发现一个模块的构建也是有迹可循的
- 创建moudle
- 编写pom,导入依赖
- 编写boot配置文件 yml
- 主启动类
- 编写业务类
- 测试
一般来说都是这个几个步骤
那我们跟着来
首先是创建模块
之后引入需要的依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>cloud2020</artifactId> <groupId>com.atguigu.springcloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-provider-payment8001</artifactId> <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
之后编写相关的配置文件 application.Yml
server: port: 8001 spring: application: name: cloud-payment-service datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: org.gjt.mm.mysql.Driver url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: 123456 mybatis: mapperLocations: classpath:mapper/*.xml type-aliases-package: com.atguigu.springcloud.entities
编写业务类
实体类
package com.atguigu.springcloud.entities; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; @Data @AllArgsConstructor @NoArgsConstructor public class Payment implements Serializable { private Long id; private String serial; }
Json封装体CommonResult
package com.atguigu.springcloud.entities; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor public class CommonResult <T>{ private Integer code; private String message; private T data; public CommonResult(Integer code,String message){ this(code,message,null); } }
mapper与映射文件
mapper接口
package com.hyc.cloud.mapper; import com.hyc.cloud.pojo.payment; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @Mapper public interface PaymentMapper { public int create(payment payment); public payment getPaymentByid(@Param("id") long id); }
对应的映射文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.hyc.cloud.mapper.PaymentMapper"> <insert id="create" parameterType="com.hyc.cloud.pojo.payment" useGeneratedKeys="true" keyProperty="id"> insert into db01.paymemt (serial) values (#{name}); </insert> <select id="getPaymentByid" resultType="com.hyc.cloud.pojo.payment" parameterType="long" resultMap="BaseResultMap"> select * from paymemt where id = #{id}; </select> <resultMap id="BaseResultMap" type="com.hyc.cloud.pojo.payment"> <id column="id" property="id" jdbcType="BIGINT"/> <id column="serial" property="serial" jdbcType="VARCHAR"/> </resultMap> </mapper>
服务层
package com.atguigu.springcloud.service; import com.atguigu.springcloud.entities.Payment; import org.apache.ibatis.annotations.Param; public interface PaymentService { public int create(Payment payment); //写 public Payment getPaymentById(@Param("id") Long id); //读取 }
实现类
package com.atguigu.springcloud.service.impl; import com.atguigu.springcloud.dao.PaymentDao; import com.atguigu.springcloud.entities.Payment; import com.atguigu.springcloud.service.PaymentService; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Service; import javax.annotation.Resource; @Service public class PaymentServiceImpl implements PaymentService { @Resource private PaymentDao paymentDao; public int create(Payment payment){ return paymentDao.create(payment); } public Payment getPaymentById( Long id){ return paymentDao.getPaymentById(id); } }
最后就是controller
package com.hyc.cloud.controller; import com.hyc.cloud.pojo.CommonResult; import com.hyc.cloud.pojo.payment; import com.hyc.cloud.service.PaymentService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController @Slf4j public class PaymentController { @Resource private PaymentService paymentService; @PostMapping("payment/create") public CommonResult create(payment payment){ int result = paymentService.create(payment); log.info("****新增结果:"+result); if (result>0){ return new CommonResult(200,"插入数据库成功",result); }else { return new CommonResult(444,"插入数据库失败",null); } } @GetMapping("payment/get/{id}") public CommonResult getPaymentByid(@PathVariable("id") long id){ payment payment = paymentService.getPaymentByid(id); log.info("****新增结果:"+payment); if (payment!=null){ return new CommonResult(200,"查询成功",payment); }else { return new CommonResult(444,"没有对应的记录,失败,查询id"+id,null); } } }
编写主启动类
package com.hyc.cloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class paymentMain8001 { public static void main(String[] args) { SpringApplication.run(paymentMain8001.class,args); } }
测试即可
支付模块,消费者者
走过一遍流程,那我们就加快速度
新建消费者子模块
cloud-consumer-order80
修改pom文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>cloud2020</artifactId> <groupId>com.hyc.springcloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-consumer-order80</artifactId> <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
配置文件消费者十分的简单,就是配置一下端口号server: port: 80
之后复制实体类到消费者项目里
那么思考一个问题
我们现在不再是单一的项目而是两个项目,那么如果调动到接口呢???
springboot中有很多的template供我们使用
这里我们要用到的就是其中的resttemplate
他和网络编程中的httpclient有异曲同工之妙
这里我们需要编写一个config类,springboot需要什么我们就new什么
@Configuration public class orderConfig { @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } }
有了这个我们就可以在消费者里面调用resttemplate
了
因为是消费者所以我们只需要知道怎么使用服务就可以了
这里我们编写controller
package com.hyc.cloud.controller; import com.hyc.cloud.pojo.CommonResult; import com.hyc.cloud.pojo.payment; import io.micrometer.core.instrument.Meter; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; @RestController public class orderContorller { @Resource private RestTemplate restTemplate; public final static String PAYMENT_URL = "http://localhost:8001";//服务提供者的地址(后面做负载均衡的时候会替换成application.name) @GetMapping("/consumer/payment/create") public CommonResult create(payment payment){ return restTemplate.postForObject(PAYMENT_URL+"/payment/create",payment,CommonResult.class); } @GetMapping("/consumer/payment/get/{id}") public CommonResult getPament(@PathVariable("id") long id){ return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+ id,CommonResult.class); } }
到这里启动测试
是不是以为这样就结束了?
当然不是
这里是的插入数据是存在问题的
会出现只有自增的主键没有内容
这个时候我们要回到服务提供者
在新增的对象参数前加上注解@requestbody
这个主机再次测试就解决了
@PostMapping("payment/create") public CommonResult create(@RequestBody payment payment){ int result = paymentService.create(payment); log.info("****新增结果:"+result); if (result>0){ return new CommonResult(200,"插入数据库成功",result); }else { return new CommonResult(444,"插入数据库失败",null); } }
此时的数据库也新增成功了
到这里呢支付模块为例 体验demo就结束了
SpringCloud Netflix-springcloudnetflix(二)https://developer.aliyun.com/article/1469569