❤️作者简介:2022新星计划第三季云原生与云计算赛道Top5🏅、华为云享专家🏅、云原生领域潜力新星🏅
💛博客首页:C站个人主页🌞
💗作者目的:如有错误请指正,将来会不断的完善笔记,帮助更多的Java爱好者入门,共同进步!
文章目录
1:创建一个空Maven项目,删除src目录

2:父POM
<!-- 修改打包方式为pom-->
<packaging>pom</packaging>
<properties>
<!-- springcloud的版本-->
<spring.cloud-version>Hoxton.RELEASE</spring.cloud-version>
<!-- springBoot的版本-->
<spring.boot-version>2.2.4.RELEASE</spring.boot-version>
<!-- 防止idea发疯,编译一直都是java5-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven.compiler.source>10</maven.compiler.source>
<maven.compiler.target>10</maven.compiler.target>
<encoding>UTF-8</encoding>
</properties>
<!-- dependencyManagement是用定义依赖的,并没有直接引入依赖,作用是控制父子模块的依赖版本一致性问题,
子模块通过不加version,version会自动的去父pom找到定义好的依赖版本,这样兼容性就会大大提升
-->
<dependencyManagement>
<!-- springcloud总依赖-->
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--springBoot总依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 引入Mybatis-->
<!-- 注意:一定要导入mybatis的springBoot启动器,不要直接导入mybatis依赖,不然会没效果-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- druid数据库连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<!-- mybatis的静态资源过滤,也就是过滤Mapper.xml,我们也可以这样想,xml文件是放在resources目录下的,放在java
目录下不会被扫描,所以我们要过滤java目录中的xml
-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
3.创建一个子模块,作微服务的提供者,端口号为8001

里面代码如下。。。
deptController
@RestController
public class deptController {
private deptService deptService;
@Autowired
@Qualifier("deptServiceImpl")
public void setDeptService(com.boot.service.deptService deptService) {
this.deptService = deptService;
}
@GetMapping(path = "/queryAllDept")
public List<dept> queryAllDept(){
return deptService.queryAllDept();
}
}
dao层。deptMapper
@Mapper //把这个Mapper接口变成可以注入的Bean,*****一定要。
@Repository //变成组件 ***一定要
public interface deptMapper {
List<dept> queryAllDept();
}
Mapper.xml
<?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.boot.dao.deptMapper">
<select id="queryAllDept" resultType="com.pojo.dept">
select deptid,deptName from dept;
</select>
</mapper>
service层省略,和普通springBoot项目构建是一样的
application.yml(8001)
server:
port: 8001
spring:
application:
# 微服务名
name: provider_dept8001/8002
datasource:
url: jdbc:mysql://localhost:3306/ssmrl?serverTimezone=UTC
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 18420163207
type: com.alibaba.druid.pool.DruidDataSource
创建一个子模块(springcloud-02-api),专门放实体类

public class dept implements Serializable {
private String deptid;
private String deptName;
public dept() {
}
public dept(String deptid, String deptName) {
this.deptid = deptid;
this.deptName = deptName;
}
public String getDeptid() {
return deptid;
}
public void setDeptid(String deptid) {
this.deptid = deptid;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
@Override
public String toString() {
return "dept{" +
"deptid='" + deptid + '\'' +
", deptName='" + deptName + '\'' +
'}';
}
}
创建另外一个子模块,springcloud-02-provider-dept8002
把springcloud-02-provider-dept8001代码全部复制上去,修改配置文件application.yml(8002)
server:
port: 8002
spring:
application:
# 微服务名
name: provider_dept8001/8002
datasource:
url: jdbc:mysql://localhost:3306/ssmrl?serverTimezone=UTC
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 18420163207
type: com.alibaba.druid.pool.DruidDataSource
为什么我们要复制多一份微服务提供者代码?
因为考虑到后面我们要使用负载均衡ribbon或者openFeign(不过底层也是ribbon)
4.创建子模块springcloud-02-comsumer-dept80
controller层:
@RestController
public class deptController80 {
@Autowired
private RestTemplate restTemplate;
private final String URL_DEPT="http://localhost:8001/";
@GetMapping("/comsumer/queryAllDept")
public List<dept> queryAllDept80(){
List<dept> res = restTemplate.getForObject(URL_DEPT + "queryAllDept", List.class);
return res;
}
}
因为默认的RestTemplate没有放入IOC容器中(也就是没有Bean),我们需要手动的放入IOC容器
config层
@Configuration
public class restTemplateConfig {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
application.yml(80)
server:
port: 80
#
spring:
application:
name: comsumer_dept80
为什么微服务消费者层的端口是80,因为80端口可以省略不写,就比如我们打开百度,也是不需要写端口号的,因为微服务消费者层是给用户去访问的
消费者层只需要Controller去远程调用提供者的Controller方法即可,所以消费者层—不能—有dao,service层
这样提供者和消费者就搭建好了,接下来我们可以引入SpringCloud组件了。。。。。。。
配置如下:

创建子模块springcloud-02-eureka7001(eureka注册中心服务端)
pom.xml
<dependencies>
<!-- web和actuator是必备的,******除了gateway网关不能加入web包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- actuator用来监控-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- eureka Server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
eureka模块主启动类
@SpringBootApplication
@EnableEurekaServer //开启Eureka服务器
public class SpringBootApplication7001 {
public static void main(String[] args) {
SpringApplication.run(SpringBootApplication7001.class,args);
}
}
application.yml(7001)
server:
port: 7001
# 配置eureka
eureka:
instance:
hostname: eureka-server7001.com
client:
register-with-eureka: false
fetchRegistry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:7001/eureka/
给提供者springcloud-02-provider-dept8001和8002修改如下
@SpringBootApplication
@EnableEurekaClient //eureka客户端
public class SpringBootApplication8001 {
public static void main(String[] args) {
SpringApplication.run(SpringBootApplication8001.class,args);
}
}
server:
port: 8001
spring:
application:
# 微服务名
name: provider_dept
datasource:
url: jdbc:mysql://localhost:3306/ssmrl?serverTimezone=UTC
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 18420163207
type: com.alibaba.druid.pool.DruidDataSource
# eureka Client
eureka:
client:
service-url:
defaultZone: http://eureka-server7001.com:7001/eureka/
register-with-eureka: true
fetch-registry: false
instance:
instance-id: eureka-client8001
server:
port: 8002
spring:
application:
# 微服务名
name: provider_dept
datasource:
url: jdbc:mysql://localhost:3306/ssmrl?serverTimezone=UTC
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 18420163207
type: com.alibaba.druid.pool.DruidDataSource
# eureka
eureka:
client:
fetch-registry: false
register-with-eureka: true
service-url:
defaultZone: http://eureka-server7001.com:7001/eureka/
instance:
prefer-ip-address: true
instance-id: eureka-client8002

。。。取名要规范。。。
创建springcloud-02-eureka7002和7003两个模块
application.yml(7001)
server:
port: 7001
# 配置eureka
eureka:
instance:
hostname: eureka-server7001.com
client:
register-with-eureka: false
fetchRegistry: false
service-url:
defaultZone: http://eureka-server7002.com:7002/eureka/,http://eureka-server7003.com:7003/eureka/ #集群版就修改这个。单机认自己,集群认其他
application.yml(7002)
server:
port: 7002
spring:
application:
name: eureka7002 #这里可有可无,除了微服务提供者。
eureka:
instance:
hostname: eureka-server7002.com
client:
fetch-registry: false
register-with-eureka: false
service-url:
defaultZone: http://eureka-server7001.com:7001/eureka/,http://eureka-server7003.com:7003/eureka/
application.yml(7003)
server:
port: 7003
spring:
application:
name: eureka7003
eureka:
instance:
hostname: eureka-server7003.com
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://eureka-server7001.com:7001/eureka/,http://eureka-server7002.com:7002/eureka/
其实Eureka集群没啥变化,也就是修改了serviceUrl的defaultZone罢了。记住一句话,单机版认自己,集群版认其他
在8001和8002微服务中修改defaultZone。
eureka:
client:
service-url:
defaultZone: http://eureka-server7001.com:7001/eureka/, http://eureka-server7002.com:7002/eureka/, http://eureka-server7003.com:7003/eureka/
还有8001和8002的微服务名要一致(spring.application.name)
spring:
application:
# 微服务名
name: provider-dept #8001和8002要一致
在springcloud-02-comsumer-dept80消费者层
@Configuration
public class restTemplateConfig {
@Bean
@LoadBalanced //开启负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
@SpringBootApplication
@EnableEurekaClient
public class SpringBootApplication80 {
public static void main(String[] args) {
SpringApplication.run(SpringBootApplication80.class,args);
}
}
用Ribbon+RestTemplate员工调用提供者的Controller方法
@RestController
public class deptController80 {
@Autowired
private RestTemplate restTemplate;
private final String URL_DEPT="http://PROVIDER-DEPT/"; //实现负载均衡用提供者微服务名代替IP:Port
@GetMapping("/comsumer/queryAllDept")
public List<dept> queryAllDept80(){
List<dept> res = restTemplate.getForObject(URL_DEPT + "queryAllDept", List.class);
return res;
}
}
application.yml(80)
server:
port: 80
#
spring:
application:
name: comsumer-dept80
eureka:
client:
fetch-registry: true
register-with-eureka: false
service-url:
defaultZone: http://eureka-server7001.com:7001/eureka/,http://eureka-server7002.com:7002/eureka/,http://eureka-server7003.com:7003/eureka/

ribbon不支持微服务名有下划线(_),修改过来即可
spring:
application:
# 微服务名
name: provider-dept
#暴露端点。使用actuator功能
management:
endpoints:
web:
exposure:
include: "*"

创建子模块springcloud-02-comsumer-openFeign-dept80
所需的依赖
<!-- OpenFeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
点进去看看

我们可以发现,Feign/openFeign的底层就是Ribbon,所以openFeign自带了负载均衡的功能,相较于Ribbon+restTemplate,openFeign无需手动的使用@LoadBalanced注解来开启负载均衡,而Ribbon需要在restTemplate的Bean上加这个注解才有负载均衡的能力
主启动类
@SpringBootApplication
@EnableFeignClients //开启Feign的客户端支持
public class springApplicationFeign80 {
public static void main(String[] args) {
SpringApplication.run(springApplicationFeign80.class,args);
}
}
编写微服务接口
@Service
@FeignClient("PROVIDER-DEPT") //标注这个微服务接口是属于“PROVIDER-DEPT”这个微服务的
public interface deptService {
//下面的代码直接从微服务提供者的controller复制过来即可
@GetMapping(path = "/queryAllDept")
public List<dept> queryAllDept();
}
然后便是使用
@RestController
public class deptController {
@Autowired
private deptService deptService;
@RequestMapping("/feign/queryAllDept")
public List<dept> queryAllDept(){
return deptService.queryAllDept();
}
}
错误类型:

原因是我们没有在提供者加上@PathVariable或者@RequestParam注解
解决方法一:在提供者加上@RequestParam注解(每个提供者传入的参数都要加上这个注解)
@RestController
public class deptController {
private deptService deptService;
@Value("${server.port}")
private String port;
@Autowired
@Qualifier("deptServiceImpl")
public void setDeptService(com.boot.service.deptService deptService) {
this.deptService = deptService;
}
@GetMapping(path = "/queryAllDept")
@HystrixCommand(fallbackMethod = "queryAllDept_Hystrix",commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled",value = "true"),
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "20000"),//注意这是毫秒。1秒=1000毫秒
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "50")
})
public List<dept> queryAllDept(@RequestParam("id") String id){
List<dept> depts = deptService.queryAllDept();
depts.add(new dept("999",port));
if(Integer.parseInt(id)<0){
throw new RuntimeException();
}
return depts;
}
/**
* 服务熔断
*/
public List<dept> queryAllDept_Hystrix(@RequestParam("id") String id){
List<dept> depts = deptService.queryAllDept();
depts.add(new dept("1066","Break"));
return depts;
}
}
修改openFeign的微服务接口
@Service
@FeignClient("PROVIDER-DEPT")
public interface deptService {
@GetMapping(path = "/queryAllDept")
public List<dept> queryAllDept(@RequestParam("id") String id);
}
没有报错了!!!

解决方法二:在微服务提供者加上@PathVariable注解。。
省略!!!
❤️💛🧡本章结束,我们下一章见❤️💛🧡
?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO
我刚刚看到whitehouse.gov正在使用drupal作为CMS和门户技术。drupal的优点之一似乎是很容易添加插件,而且编程最少,即重新发明轮子最少。这实际上正是Ruby-on-Rails的DRY理念。所以:drupal的缺点是什么?Rails或其他基于Ruby的技术有哪些不符合whitehouse.org(或其他CMS门户)门户技术的资格? 最佳答案 Whatarethedrawbacksofdrupal?对于Ruby和Rails,这确实是一个相当主观的问题。Drupal是一个可靠的内容管理选项,非常适合面向社区的站点。它
当音乐碰上区块链技术,会擦出怎样的火花?或许周杰伦已经给了我们答案。8月29日下午,B站独家首发周杰伦限定珍藏Demo独家访谈VCR,周杰伦在VCR里分享了《晴天》《青花瓷》《搁浅》《爱在西元前》四首经典歌曲Demo背后的创作故事,并首次公布18年前未发布的神秘作品《纽约地铁》的Demo。在VCR中,方文山和杰威尔音乐提及到“多亏了区块链技术,现在我们可以将这些Demos,变成独一无二具有收藏价值的艺术品,这些Demos可以在薄盒(国内数藏平台)上听到。”如何将音乐与区块链技术相结合,薄盒方面称:“薄盒作为区块链技术服务方,打破传统对于区块链技术只能作为数字收藏的理解。聚焦于区块链技术赋能,在
目录SpringBootStarter是什么?以前传统的做法使用SpringBootStarter之后starter的理念:starter的实现: 创建SpringBootStarter步骤在idea新建一个starter项目、直接执行下一步即可生成项目。 在xml中加入如下配置文件:创建proterties类来保存配置信息创建业务类:创建AutoConfiguration测试如下:SpringBootStarter是什么? SpringBootStarter是在SpringBoot组件中被提出来的一种概念、简化了很多烦琐的配置、通过引入各种SpringBootStarter包可以快速搭建出一
我感到有点困惑——大约24小时以来,我一直在考虑在我的项目中使用哪种组播技术。基本上,我需要的是:创建组(通过一些后端进程)任意客户端广播消息(1:N,N:N)(可能)直接消息(1:1)(重要)使用我自己的后端(例如,通过某种HTTPAPI)对客户端进行身份验证/授权能够通过后端进程(或服务器插件)踢出特定的客户端这是我要的:Ruby或Haxe中的后端相关流程JS+Haxe(Flash9)中的前端—在浏览器中,因此理想情况下通过80/443进行通信,但不一定。因此,这项技术必须能够在HaxeforFlash中轻松访问,最好是Ruby。我一直在考虑:RabbitMQ(或OpenAMQ)、
文章目录概述背景为何要存算分离优势**应用场景**存算分离产品技术流派华为JuiceFSHashDataXSKY概述背景Hadoop一出生就是奔存算一体设计,当时设计思想就是存储不动而计算(code也即是代码程序)动,负责调度Yarn会把计算任务尽量发到要处理数据所在的实例上,这也是与传统集中式存储最大的不同。为何当时Hadoop设计存算一体的耦合?要知道2006年服务器带宽只有100Mb/s~1Gb/s,但是HDD也即是磁盘吞吐量有50MB/s,这样带宽远远不够传输数据,网络瓶颈尤为明显,无奈之举只好把计算任务发到数据所在的位置。众观历史常言道天下分久必合合久必分,随着云计算技术的发展,数据
文章目录华为OD面试流程1.mysql数据库建了两个字段,且设置了联合索引,如果其中有一个字段为空会出现什么问题?2.谈谈springIOC的理解,有什么好处,解决了什么问题3.谈谈springAOP的理解,切面编程有没有实际应用,有哪些注解,作用是什么,有那些应用场景?4.Erika和zookeeper有了解过吗,作用是什么,主要解决了什么问题5.谈谈JDK、JRE、JVM的理解,区别是什么6.谈谈对泛型的理解7.JVM的组成华为OD面试流程机试:三道算法题,关于机试,橡皮擦已经准备好了各语言专栏,可以直接订阅。性格测试:机试技术一面(本专栏核心)技术二面(本专栏核心)主管面试定级定薪发of
解开谜团:深入探索ChatGPT的技术奇迹。ChatGpt无处不在,无论是在播客、博客、YouTube还是社交媒体上。当我注意到这项新技术如此受欢迎时,我决定试一试,我被震惊了!有很多关于ChatGpt及其魔力的博客,但在这篇博客中,我将深入探讨其内部技术及其工作原理!ChatGpt简介根据OpenAI,ChatGpt被描述为:“我们训练了一个名为ChatGpt的模型,它以对话方式进行交互。对话格式使ChatGpt可以回答后续问题、承认错误、挑战不正确的前提并拒绝不适当的请求。ChatGPT是InstructGPT的兄弟模型,它经过训练可以按照提示中的说明进行操作并提供详细的响应。”OpenA