SpringCloud学习 系列三、 创建一个没有使用springCloud的服务提供者和消费者
系列导航
SpringCloud学习 系列一、 前言-为什么要学习微服务
SpringCloud学习 系列三、 创建一个没有使用springCloud的服务提供者和消费者
SpringCloud学习 系列四、微服务中心 Eureka介绍及创建一个Eureka中心服务
SpringCloud学习 系列五、创建生产者和消费者验证微服务中心 Eureka的作用
SpringCloud学习 系列七、EurekaServer集群创建
SpringCloud学习 系列十、服务熔断与降级(1-简介)
SpringCloud学习 系列十、服务熔断与降级(2-方法级别服务降级)
SpringCloud学习 系列十、服务熔断与降级(3-类级别的服务降级)
SpringCloud学习 系列十、服务熔断与降级(4-Dashboard监控仪表盘)
本系列教程期望达到的效果是,看完之后不仅仅对springCloud能干什么有所了解,更重要的是看完之后就能上手实现这些功能。好多教程写的非常好理论很全面,但是实验部分源码和测试用例不全,或者有跳跃导致读者无法独立完成实验内容,最终只是知道能干什么但是自己却不能实现出来。本系列教程将会逐步将我自己掌握的一些知识点以实验的方式展示给大家,希望大家有所收获,逐步更新中敬请期待。
创建一个没有使用springCloud的服务提供者和消费者
为了阐述为什么要用SpringCloud,本例先创建一个没有使用SpringCloud的消费者和供者的服务,然后分析一下这样的工程有什么不缺点。注:本系列中所有的实例都使用 MySQL 数据库,使用 mybatis-plus 作为持久层技术。
(1)数据库中创建表
CREATE TABLE `block_t` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8; 插入实验数据:
INSERT INTO `block_t` VALUES ('1', 'oracle');
INSERT INTO `block_t` VALUES ('2', 'mysql');
INSERT INTO `block_t` VALUES ('3', '达梦');
INSERT INTO `block_t` VALUES ('4', '金仓');
INSERT INTO `block_t` VALUES ('5', 'mongo');
INSERT INTO `block_t` VALUES ('6', 'redis');
(2)创建一个空的工程



上图:Jdk选择1.8版本
3)创建一个provider模块(服务提供者)
模块名称:01-provider-8081(该模块非常重要,后面好多工程都要在该基础上进行修改,一定要保证该工程的正确性)
主要提供对表block_t的单条查询和批量查询功能。

上图:创建一个module



上图:随便选一个版本,后面直接修改pom.xml文件改成需要的版本即可。
删除如下这些没有用的文件。

pom.xml文件
<?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.springcloud</groupId>
<artifactId>01-provider-8081</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>01-provider-8081</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.1.6.RELEASE</spring-boot.version>
</properties> <dependencies> <!-- mysql 数据库连接驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
<scope>runtime</scope>
</dependency> <!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency> <!-- mybatis-plus-generator 代码自动生成-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.1</version>
</dependency> <!-- 省略get/set等方法 日志打印 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency> <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency> <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>
</dependencies> <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.17.RELEASE</version>
<configuration>
<mainClass>com.springcloud.ApplicationProvider8081</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build> </project>
配置文件

package com.springcloud.controller; import com.springcloud.domain.Block;
import com.springcloud.service.IBlockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.Map; /**
* <p>
* 前端控制器。
* </p>
*
* @author yc
* @since 2022-07-15
*/ @RestController
@RequestMapping("/provider")
public class BlockController { @Autowired
private IBlockService iBlockService; /**
* 单记录新增。
*
* @param block 参数说明
* @return AjaxResult
*/
@PostMapping(value = "/block/add")
@ResponseBody
public int addSave(@Valid Block block) {
return iBlockService.insert(block);
} /**
* 获取数据列表。
*
* @return map
*/
@GetMapping(value = "/block/list")
@ResponseBody
public Map list( ) {
Map map = iBlockService.selectList(null);
return map;
} /**
* 根据id查询单条数据。
*
* @param blockId 参数说明
* @return Block
*/
@GetMapping(value = "/block/get/{blockId}")
@ResponseBody
public Block get(@PathVariable("blockId") Integer blockId) {
Block block = iBlockService.selectById(blockId);
return block;
} /**
* 修改保存。
* @param block 参数说明
* @return int
*/
@PostMapping(value = "/block/update/{blockId}")
@ResponseBody
public int editSave(@PathVariable("blockId")Integer blockId,@Valid Block block){
block.setId(blockId);
return iBlockService.edit(block) ;
} /**
* 根据id删除单条数据。
*
* @param blockId 参数说明
* @return int
*/
@PostMapping(value = "/block/delete/{blockId}")
@ResponseBody
public int remove(
@NotNull(message = "id不能为空!") @PathVariable("blockId") Integer blockId) {
return iBlockService.delete(blockId);
}
}
package com.springcloud.domain; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; /**
* <p>
* 。
* </p>
*
* @author yc
* @since 2022-07-15
*/
@TableName(value = "BLOCK_T")
public class Block {
private static final long serialVersionUID = 1L; @TableId
private Integer id; private String name; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public void setName(String name) {
this.name = name;
} public String getName() {
return name;
} @Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("name", getName())
.toString();
}
}
package com.springcloud.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.springcloud.domain.Block; /**
* <p>
* Mapper 接口。
* </p>
*
* @author yc
* @since 2022-07-15
*/
public interface BlockMapper extends BaseMapper<Block> { }
package com.springcloud.service; import com.springcloud.domain.Block; import java.util.Map; /**
* <p>
* 服务类。
* </p>
*
* @author yc
* @since 2022-07-15
*/
public interface IBlockService {
/**
* 获取数据列表。
*
* @param block 参数说明
* @return List
*/
Map selectList(Block block); /**
* 获取单条数据。
*
* @param departId 参数说明
* @return Depart
*/
Block selectById(Integer departId); /**
* 单记录新增。
*
* @param block 参数说明
* @return status
*/
int insert(Block block); /**
* 修改保存。
*
* @param block 参数说明
* @return status
*/
int edit(Block block); /**
* 根据id删除单条数据。
*
* @param id 参数说明
* @return status
*/
int delete(Integer id);
}
package com.springcloud.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.springcloud.domain.Block;
import com.springcloud.mapper.BlockMapper;
import com.springcloud.service.IBlockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import java.util.HashMap;
import java.util.List;
import java.util.Map; /**
* <p>
* 服务实现类。
* </p>
*
* @author yc
* @since 2022-07-15
*/
@Service
public class BlockServiceImpl implements IBlockService {
@Autowired
BlockMapper blockMapper; /**
* 获取数据列表。
*
* @param block 参数说明
* @return List
*/
@Override
public Map selectList(Block block) {
Map<String, List> reusltMap = new HashMap<>();
reusltMap.put("dataList", blockMapper.selectList(new QueryWrapper<>(block)));
return reusltMap;
} /**
* 根据id获取单条数据。
*
* @param departId 参数说明
* @return Depart
*/
@Override
public Block selectById(Integer departId) {
return blockMapper.selectById(departId);
} /**
* 单记录新增。
*
* @param block 参数说明
* @return status
*/
@Override
public int insert(Block block) {
return blockMapper.insert(block);
} /**
* 修改保存。
*
* @param block 参数说明
* @return status
*/
@Override
public int edit(Block block) {
return blockMapper.updateById(block);
} /**
* 根据id删除单条数据。
*
* @param id 参数说明
* @return status
*/
@Override
public int delete(Integer id) {
return blockMapper.deleteById(id);
}
}
package com.springcloud; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
@MapperScan("com.springcloud.mapper") //这里要注意扫描mapper文件
public class ApplicationProvider8081 { public static void main(String[] args) {
SpringApplication.run(ApplicationProvider8081.class, args);
} }
(4)创建一个consumer模块(服务使用者)
模块名称:01-consumer-8080(该模块非常重要,后面好多工程都要在该基础上进行修改,一定要保证该工程的正确性)
主要提供调用provider模块中对表block_t的单条查询和批量查询功能的controller。
方法类似上面的步骤不在重复。
pom.xml
<?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.springcloud</groupId>
<artifactId>01-consumer-8080</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>01-consumer-8081</name>
<description>Demo project for Spring Boot</description> <properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.1.6.RELEASE</spring-boot.version>
</properties> <dependencies> <!-- 省略get/set等方法 日志打印 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency> <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency> <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>
</dependencies> <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.17.RELEASE</version>
<configuration>
<mainClass>com.springcloud.ApplicationConsumer8080</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build> </project>
配置文件

package com.springcloud.configure; import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
import org.springframework.web.client.RestTemplate; @Controller
public class BlockCodeConfigure { @Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
package com.springcloud.controller; import com.springcloud.domain.Block;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.util.Map; /**
* <p>
* 前端控制器。
* </p>
*
* @author yc
* @since 2022-07-15
*/ @RestController
@RequestMapping("/consumer")
public class BlockController { @Autowired
private RestTemplate restTemplate;
private static final String SERVICE_PROVIDER = "http://localhost:8081"; /**
* 获取数据列表。
*
* @param block 参数说明
* @return map
*/
@GetMapping(value = "/block/list")
@ResponseBody
public Map list(Block block) {
String url = SERVICE_PROVIDER + "/provider/block/list";
return restTemplate.getForObject(url, Map.class);
} /**
* 根据id查询单条数据。
*
* @param blockId 参数说明
* @return Block
*/
@GetMapping(value = "/block/get/{blockId}")
@ResponseBody
public Block get(@PathVariable("blockId") Integer blockId) {
String url = SERVICE_PROVIDER + "/provider/block/get/"+blockId;
return restTemplate.getForObject(url, Block.class);
} }
package com.springcloud.domain; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; /**
* <p>
* 。
* </p>
*
* @author yc
* @since 2022-07-15
*/ public class Block {
private static final long serialVersionUID = 1L; private Integer id; private String name; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public void setName(String name) {
this.name = name;
} public String getName() {
return name;
} @Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("name", getName())
.toString();
}
}
package com.springcloud; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
public class ApplicationConsumer8080 { public static void main(String[] args) {
SpringApplication.run(ApplicationConsumer8080.class, args);
} }
删除如下这些没用的文件

(5) 效果展示
<1>直接调用01-provider-8081工程中的接口(只看单条查询的接口)


<2>调用01-consumer-8080中的接口,01-consumer-8080中的接口在调用01-provider-8081工程中的接口(只看单条查询的接口)

6、这种服务存在的问题
(1)01-consumer-8080中直接调用服务者的服务,只能写一个服务者的地址,01-provider-8081挂了就没有服务了。
(2)调用服务提供者使用的是ip而不是服务名,如果服务提供者更换了主机,服务调用者也得修改代码。
(3)如果有很多consumer,服务提供者provider的压力无法分担容易出现性能瓶颈。
如何解决这个问题就要进入下一章“微服务中心 Eureka”
SpringCloud学习 系列三、 创建一个没有使用springCloud的服务提供者和消费者的更多相关文章
- SpringCloud学习6-如何创建一个服务消费者consumer
上一节如何创建一个服务提供者provider已经启动了一个provider的server,提供用户信息查询接口.接下来,我们启动另一个provider,由于是同一台机器本地测试,我们换一个端口 --s ...
- SpringCloud学习5-如何创建一个服务提供者provider
前几篇主要集中在注册中心eureka的使用上,接下来可以创建服务提供者provider来注册到eureka. demo源码见: https://github.com/Ryan-Miao/spring- ...
- SpringCloud学习系列之一 ----- 搭建一个高可用的注册中心(Eureka)
前言 本篇主要介绍的是SpringCloud相关知识.微服务架构以及搭建一个高可用的服务注册与发现的服务模块(Eureka). SpringCloud介绍 Spring Cloud是在Spring B ...
- SpringCloud学习系列之三----- 断路器(Hystrix)和断路器监控(Dashboard)
前言 本篇主要介绍的是SpringCloud中的断路器(Hystrix)和断路器指标看板(Dashboard)的相关使用知识. SpringCloud Hystrix Hystrix 介绍 Netfl ...
- SpringCloud学习系列之七 ----- Zuul路由网关的过滤器和异常处理
前言 在上篇中介绍了SpringCloud Zuul路由网关的基本使用版本,本篇则介绍基于SpringCloud(基于SpringBoot2.x,.SpringCloud Finchley版)中的路由 ...
- scrapy爬虫学习系列三:scrapy部署到scrapyhub上
系列文章列表: scrapy爬虫学习系列一:scrapy爬虫环境的准备: http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_python_00 ...
- DocX开源WORD操作组件的学习系列三
DocX学习系列 DocX开源WORD操作组件的学习系列一 : http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_sharp_001_docx1.htm ...
- RabbitMQ学习系列三-C#代码接收处理消息
RabbitMQ学习系列三:.net 环境下 C#代码订阅 RabbitMQ 消息并处理 http://www.80iter.com/blog/1438251320680361 http://www. ...
- .net reactor 学习系列(三)---.net reactor代码自动操作相关保护功能
原文:.net reactor 学习系列(三)---.net reactor代码自动操作相关保护功能 接上篇,上篇已经学习了界面的各种功能以及各种配置,这篇准备学习下代码控制许可证. ...
- MyBatis学习系列三——结合Spring
目录 MyBatis学习系列一之环境搭建 MyBatis学习系列二——增删改查 MyBatis学习系列三——结合Spring MyBatis在项目中应用一般都要结合Spring,这一章主要把MyBat ...
随机推荐
- [USACO2022OPEN S] COW Operations S
题目描述 Bessie 找到了一个长度不超过 \(2 \cdot 10^5\) 且仅包含字符 'C','O' 和 'W' 的字符串 \(s\).她想知道是否可以使用以下操作将该字符串变为单个字母 'C ...
- vue-test --------模板引用
<template> <input type="text" v-model.lazy="message"> <div>{{m ...
- VsCode运行与freopen与快读
运行 g++ -o a a.cpp && ./a g++ b.cpp -o b && ./b g++ c.cpp -o c && ./c freopen ...
- java通过url得到文件对象(支持http和https)
文字标题:java通过url得到文件对象(支持http和https) 作者:锅巴 1.场景:通过一个url地址来得到一个文件,此方式就是通过一个url将文件下载到本地的临时文件,直接上代码 /** * ...
- springboot整合mybatis步骤思路
/** * springboot整合mybatis步骤思路 * 依赖导入 * 建表 * 实体类 * mapper配置文件 * mapper接口 * yaml配置 * properties配置数据库连接 ...
- Python用辗转相除法计算两数的最大公约数和最小公倍数
计算最大公约数运用辗转相除法就行了 计算最小公倍数需要运用公式:最小公倍数=数字1*数字2/最大公约数 有关辗转相除法的知识请查看:辗转相除法 以下为代码: #计算最大公约数 def gys (x,y ...
- java判断两个日期是否连续
使用java判断两个日期的天是否连续 import java.text.SimpleDateFormat; import java.util.Date; /** * @author lingkang ...
- 华为云IoT智简联接,开启物联世界新纪元
摘要:华为云IoT将聚焦物联网技术和商业基础能力建设,联接万物.联接生态.联接行业,帮助各行各业做好数字化转型. 近日,华为云通过线上专题演讲发布了IoT最新战略.华为云IoT将聚焦物联网基础能力(包 ...
- 网络性能总不好?网络调优专家AOE帮你来“看看”
摘要:为提升网络性能.降低人工调优成本,CANN推出了自动化网络调优工具AOE,通过子图调优.算子调优与梯度调优的功能,让网络可以在AI硬件上获得最佳性能. 本文分享自华为云社区<网络性能总不好 ...
- 云小课|云小课带你玩转可视化分析ELB日志
阅识风云是华为云信息大咖,擅长将复杂信息多元化呈现,其出品的一张图(云图说).深入浅出的博文(云小课)或短视频(云视厅)总有一款能让您快速上手华为云.更多精彩内容请单击此处. 云日志服务支持可视化查看 ...