













git源码地址:https://github.com/spring-projects/spring-boot/releases/


为了稳定起见,建议用Spring boot2.x
git源码地址:https:github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release-Notes

通过上面官网发现 Boot官方强烈建议你升级到2.X以上版本。


git源码地址:https://github.com/spring-projects/spring-cloud/releases/
官网:https://spring.io/projects/spring-cloud

SpringCloud采用了英国伦敦地铁站的名称来命名,并由地铁站名称字母A-Z依次类推的形式来发布迭代版本。
SpringCloud是一个由许多子项目组成的综合项目,各个项目有不同的发布节奏。为了管理SpringCloud与各子项目的版本依赖关系,发布了一个清单,其中包括了某个SpringCloud版本对应的子项目版本。为了避免SpringCloud版本号与子项目版本混乱,SpringCloud版本采用了名称而并非版本号的命名,这些版本的名字采用了伦敦地铁站的名字,根据字母表的顺序来对应版本时间顺序。例如Angel是第一个版本,Brixton是第二个版本。当SpringCloud的发布内容积累到列节点或者一个重大Bug被解决后,会发布一个’service releases’版本,简称SRX版本,比如Greenwich.SR2就是SpringCloud发布的Greenwich版本的第2个SRX版本。



官方文档:https://spring.io/projects/spring-cloud#overview


查询网址:https://start.spring.io/actuator/info

| 工具 | 版本 |
|---|---|
| cloud | Hoxton.SR1 |
| boot | 2.2.RELEASE |
| cloud | alibaba 2.1.0.RELEASE |
| java | Java8 |
| Maven | 3.5及以上 |

org.springframework.boot
spring-boot-dependencies
2.2.2.RELEASE
pom
import
org.springframework.cloud
spring-cloud-dependencies
Hoxton.SR1
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
2.2.5.RELEASE
pom
import

Spring Cloud:https://cloud.spring.io/spring-cloud-static/Hoxton.SR1/reference/htmlsingle/
Spring Cloud中文文档:https://www.bookstack.cn/read/spring-cloud-docs/docs-index.md
Spring Boot:https://docs.spring.io/spring-boot/docs/2.2.2.RELEASE/reference/htmlsingle/

New Project

聚合总父工程名字

Maven选版本

字符编码
文件–>设置–>文本编码

注解生效激活
文件–>设置–>构建,执行,部署–>Compiler–>Annotation processors

java编译版本选8
文件–>设置–>构建,执行,部署–>Compiler–>Java Compiler

File Type过滤
文件–>设置–>编辑器–>文件类型

4.0.0
com.tedu.java
cloud2022
pom
1.0-SNAPSHOT
Maven
http://maven.apache.org/
2001
UTF-8
1.8
1.8
4.12
1.2.12
1.18.16
8.0.26
1.2.11
2.1.4
org.springframework.boot
spring-boot-dependencies
2.2.2.RELEASE
pom
import
org.springframework.cloud
spring-cloud-dependencies
Hoxton.SR1
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
2.2.5.RELEASE
pom
import
mysql
mysql-connector-java
${mysql.version}
com.alibaba
druid
${druid.version}
org.mybatis.spring.boot
mybatis-spring-boot-starter
${mybatis.spring.boot.version}
log4j
log4j
${log4j.version}
junit
junit
${junit.version}
org.projectlombok
lombok
${lombok.version}
true
org.springframework.boot
spring-boot-maven-plugin
2.6.7
true
true



创建完成后回到父工程查看pom文件变化?

cloud2022
com.tedu.java
1.0-SNAPSHOT
4.0.0
Cloud-provider-payment8001
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-actuator
org.mybatis.spring.boot
mybatis-spring-boot-starter
com.alibaba
druid-spring-boot-starter
1.1.10
mysql
mysql-connector-java
org.springframework.boot
spring-boot-starter-jdbc
org.springframework.boot
spring-boot-starter-test
test
org.projectlombok
lombok
org.springframework.boot
spring-boot-devtools
runtime
true
application.yml
server:
port: 8001
spring:
application:
name: cloud-payment-service8001
datasource:
type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型
driver-class-name: com.mysql.cj.jdbc.Driver #mysql驱动包
url: jdbc:mysql://localhost:3306/db2022_cloud?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.tedu.java.pojo #所在pojo别名类所在包
package com.tedu.java;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author 47132
*/
@SpringBootApplication
public class PayMentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PayMentMain8001.class,args);
}
}
1) 建表SQL
在数据库中新增数据库db2022_cloud,在db2022_cloud新增表payment。
CREATE TABLE `payment` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`serial` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '支付流水号',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '支付表' ROW_FORMAT = Dynamic;
2)pojo
主实体Payment:
package com.tedu.java.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @author 47132
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Payment implements Serializable {
private Long id;
private String serial;
}
Json封装体CommonResult类
package com.tedu.java.utils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author 47132
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult {
//404 not_found
private Integer code;
private String message;
private T data;
public CommonResult(Integer code,String message){
this(code,message,null);
}
}
3)dao
PaymentDao 接口
package com.tedu.java.dao;
import com.tedu.java.pojo.Payment;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* @author 47132
*/
@Mapper
public interface PaymentDao {
public int create(Payment payment);
public Payment getPaymentById(@Param("id") Long id);
}
mybatis的映射文件PaymentMapper.xml:
路径:src\main\resources\mapper\PaymentMapper.xml
insert into payment (serial) values (#{serial});
4)service
接口PaymentService
package com.tedu.java.service;
import com.tedu.java.pojo.Payment;
import org.apache.ibatis.annotations.Param;
/**
* @author 47132
*/
public interface PaymentService {
public int create(Payment payment);
public Payment getPaymentById(@Param("id") Long id);
}
实现类 PaymentServiceImpl
package com.tedu.java.service.impl;
import com.tedu.java.dao.PaymentDao;
import com.tedu.java.pojo.Payment;
import com.tedu.java.service.PaymentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class PaymentServiceImpl implements PaymentService {
@Autowired
private PaymentDao paymentDao;
@Override
public int create(Payment payment) {
return paymentDao.create(payment);
}
@Override
public Payment getPaymentById(Long id) {
return paymentDao.getPaymentById(id);
}
}
5)controller
PaymentController
package com.tedu.java.controller;
import com.tedu.java.pojo.Payment;
import com.tedu.java.service.PaymentService;
import com.tedu.java.utils.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @author 47132
*/
@RestController
@Slf4j
public class PaymentController {
@Autowired
private PaymentService paymentService;
@PostMapping(value = "/payment/create")
public CommonResult create(@RequestBody Payment payment) {
int result = paymentService.create(payment);
log.info("*******插入结果:" + result);
if (result > 0) {
return new CommonResult(200, "插入结果成功,serverPort:", result);
} else {
return new CommonResult(444, "插入结果失败!!serverPort:");
}
}
@GetMapping(value = "/payment/get/{id}")
public CommonResult getPaymentById(@PathVariable("id") Long id) {
Payment paymentResult = paymentService.getPaymentById(id);
log.info("*******插入结果为:" + paymentResult);
if (paymentResult != null) {
return new CommonResult(200, "查询结果成功,serverPort:"+serverPort, paymentResult);
} else {
return new CommonResult(444, "没有对应记录!!查询id为:"+id+",serverPort:"+serverPort);
}
}
}
运行项目,先使用postman模拟post请求,添加数据,然后查询。

org.springframework.boot
spring-boot-devtools
runtime
true
org.springframework.boot
spring-boot-maven-plugin
true
true




cloud2022
com.tedu.java
1.0-SNAPSHOT
4.0.0
cloud-consumer-order80
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-devtools
runtime
true
org.projectlombok
lombok
server:
port: 80
spring:
application:
name: cloud-comsumer-order80
package com.tedu.java;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author 47132
*/
@SpringBootApplication
public class OrderMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderMain80.class,args);
}
}
package com.tedu.java.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @author 47132
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Payment implements Serializable {
private Long id;
private String serial;
}
Json封装体CommonResult类
package com.tedu.java.utils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author 47132
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult {
//404 not_found
private Integer code;
private String message;
private T data;
public CommonResult(Integer code,String message){
this(code,message,null);
}
}

package com.tedu.java.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @author 47132
*/
@Configuration
public class ApplicationContextConfig {
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
package com.tedu.java.controller;
import com.tedu.java.pojo.Payment;
import com.tedu.java.utils.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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;
/**
* @author 47132
*/
@RestController
@Slf4j
public class OrderController {
public static final String PAYMENT_URL="HTTP://localhost:8001";
@Autowired
private RestTemplate restTemplate;
@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 getPayment(@PathVariable("id") Long id){
return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
}
}
先启动8001,再启动80,然后浏览器访问http://localhost/consumer/payment/get/1

系统中有重复部分,重构。

cloud2022
com.tedu.java
1.0-SNAPSHOT
4.0.0
cloud-api-commons
org.springframework.boot
spring-boot-devtools
runtime
true
org.projectlombok
lombok
true
cn.hutool
hutool-all
5.8.6
主实体Payment:
package com.tedu.java.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @author 47132
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Payment implements Serializable {
private Long id;
private String serial;
}
Json封装体CommonResult类
package com.tedu.java.utils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author 47132
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonResult {
//404 not_found
private Integer code;
private String message;
private T data;
public CommonResult(Integer code,String message){
this(code,message,null);
}
}

com.tedu.java
cloud-api-commons
1.0-SNAPSHOT

Spring Cloud封装了Netflix 公司开发的Eureka模块来实现服务治理。
在传统的rpc远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务与服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册。
Erueka采用了CS的设计架构,Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用Eureka的客户端连接到Eureka的客户端连接到Eureka Server并维持心跳连接。这样系统的维护人员就可以通过Eureka Server 来监控系统中各个微服务是否正常运行。
在微服务注册与发现中,有一个注册中心。当服务器启动的时候,就会把当前自己服务器的信息,比如服务地址通讯地址等以别名的形式注册到注册中心上。另一方(消费者|服务者提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地RPC调用RPC远程调用框架核心设计思想;在于注册中心,因为使用注册中心管理每一个服务与服务之间的一个依赖关系(服务治理概念)。在任何rpc远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址))。


cloud2022
com.tedu.java
1.0-SNAPSHOT
4.0.0
cloud-eureka-server7001
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-actuator
com.tedu.java
cloud-api-commons
1.0-SNAPSHOT
org.springframework.boot
spring-boot-devtools
runtime
true
org.projectlombok
lombok
server:
port: 7001
spring:
application:
name: cloud-eureka-server7001
eureka:
instance:
hostname: eureka7001.com #eureka服务端的实例名称
client:
#false表示自己断就是注册中心,职责就是维护服务实例,并不是区检索服务
fetch-registry: false #不注册自己
#fasle表示不向注册中心注册自己
register-with-eureka: false # 不检索自己
service-url:
#设置与eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
defaultZone: http://eureka7001.com:7001/eureka
package com.tedu.java;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* @author 47132
*/
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7001.class,args);
}
}


No application available没有服务被发现 因为没有注册服务进来当前不可能有服务被发现。
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client

eureka:
client:
#表示是否将自己注册进eurekaServer,默认为true
register-with-eureka: true
#是否从eurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须为true,才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
#defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/ #集群版
defaultZone: http://eureka7001.com:7001/eureka
@SpringBootApplication
@EnableEurekaClient
public class PayMentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PayMentMain8001.class,args);
}
}




解决办法: 搭建Eureka注册中心集群,实现负载均衡+故障容错。
cloud2022
com.tedu.java
1.0-SNAPSHOT
4.0.0
cloud-eureka-server7002
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-actuator
com.tedu.java
cloud-api-commons
1.0-SNAPSHOT
org.springframework.boot
spring-boot-devtools
runtime
true
org.projectlombok
lombok
找到C:\Windows\System32\drivers\etc路径下的hosts文件:
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
刷新hosts文件:ipconfig /flushdns

cloud-eureka-server7001:
server:
port: 7001
spring:
application:
name: cloud-eureka-server7001
eureka:
instance:
hostname: eureka7001.com #eureka服务端的实例名称
client:
#false表示自己断就是注册中心,职责就是维护服务实例,并不是区检索服务
fetch-registry: false #不注册自己
#fasle表示不向注册中心注册自己
register-with-eureka: false # 不检索自己
service-url:
#设置与eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
defaultZone: http://eureka7002.com:7002/eureka
cloud-eureka-server7002:
server:
port: 7002
spring:
application:
name: cloud-eureka-server7002
eureka:
instance:
hostname: eureka7002.com #eureka服务端的实例名称
client:
#false表示自己断就是注册中心,职责就是维护服务实例,并不是区检索服务
fetch-registry: false #不注册自己
#fasle表示不向注册中心注册自己
register-with-eureka: false # 不检索自己
service-url:
#设置与eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
defaultZone: http://eureka7001.com:7001/eureka
package com.tedu.java;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* @author 47132
*/
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7002 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7002.class,args);
}
}
将Cloud-provider-payment8001中的application.yml修改:
server:
port: 8001
spring:
application:
name: cloud-payment-service8001
datasource:
type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型
driver-class-name: com.mysql.cj.jdbc.Driver #mysql驱动包
url: jdbc:mysql://localhost:3306/db2022_cloud?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.tedu.java.pojo #所在pojo别名类所在包
eureka:
client:
#表示是否将自己注册进eurekaServer,默认为true
register-with-eureka: true
#是否从eurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须为true,才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/ #集群版
#defaultZone: http://eureka7001.com:7001/eureka
将cloud-consumer-order80中的application.yml修改:
server:
port: 80
spring:
application:
name: cloud-comsumer-order80
eureka:
client:
#表示是否将自己注册进eurekaServer,默认为true
register-with-eureka: true
#是否从eurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须为true,才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/ #集群版
#defaultZone: http://eureka7001.com:7001/eureka
先要启动EurekaServer,7001/7002服务,再要启动服务提供者provider8001,再要启动消费者80;在浏览器中输入http://localhost/consumer/payment/get/1,观察结果。

cloud2022
com.tedu.java
1.0-SNAPSHOT
4.0.0
cloud-provider-payment8002
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-actuator
org.mybatis.spring.boot
mybatis-spring-boot-starter
com.alibaba
druid-spring-boot-starter
1.1.10
mysql
mysql-connector-java
org.springframework.boot
spring-boot-starter-jdbc
org.springframework.boot
spring-boot-starter-test
test
org.projectlombok
lombok
org.springframework.boot
spring-boot-devtools
runtime
true
com.tedu.java
cloud-api-commons
1.0-SNAPSHOT
org.springframework.boot
spring-boot-maven-plugin
true
true
server:
port: 8002
spring:
application:
name: cloud-payment-service8002
datasource:
type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型
driver-class-name: com.mysql.cj.jdbc.Driver #mysql驱动包
url: jdbc:mysql://localhost:3306/db2022_cloud?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.tedu.java.pojo #所在pojo别名类所在包
eureka:
client:
#表示是否将自己注册进eurekaServer,默认为true
register-with-eureka: true
#是否从eurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须为true,才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/ #集群版
#defaultZone: http://eureka7001.com:7001/eureka
package com.tedu.java;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* @author 47132
*/
@SpringBootApplication
@EnableEurekaClient
public class PayMentMain8002 {
public static void main(String[] args) {
SpringApplication.run(PayMentMain8002.class,args);
}
}
直接从8001粘


package com.tedu.java.controller;
import com.tedu.java.pojo.Payment;
import com.tedu.java.utils.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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;
/**
* @author 47132
*/
@RestController
@Slf4j
public class OrderController {
//public static final String PAYMENT_URL="HTTP://localhost:8001";
// 通过在eureka上注册过的微服务名称调用
public static final String PAYMENT_URL="http://CLOUD-PAYMENT-SERVICE";
@Autowired
private RestTemplate restTemplate;
@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 getPayment(@PathVariable("id") Long id){
return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
}
}
修改80端口的ApplicationContextConfig :
package com.tedu.java.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @author 47132
*/
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
先要启动EurekaServer,7001/7002服务,再要启动服务提供者provider,8001/8002服务再启动consumer;80,在浏览器输入:http://localhost/consumer/payment/get/1

修改8001和8002的application.yml,改为CLOUD-PAYMENT-SERVICE

结果:负载均衡效果达到,8001/8002端口交替出现。
因为Ribbon和Eureka整合后Consumer可以直接调用服务而不用再关心地址和端口号,且该服务还有负载功能了。

eureka:
client:
#表示是否将自己注册进eurekaServer,默认为true
register-with-eureka: true
#是否从eurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须为true,才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/ #集群版
#defaultZone: http://eureka7001.com:7001/eureka
instance:
instance-id: payment8001

8002和80也是如此。

对于注册eureka里面的微服务,可以通过服务发现来获得该服务的信息。
@Autowired
private DiscoveryClient discoveryClient;
/**
* 服务发现
*/
@GetMapping("/payment/discovery")
public Object discovery(){
List services = discoveryClient.getServices();
for(String element : services){
log.info("*********element:"+element);
}
//一个微服务小的全部实例
List instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
for (ServiceInstance instance:instances){
log.debug(instance.getServiceId()+"\t"+instance.getHost()+"\t"+instance.getPort()+"\t"+instance.getUri());
}
return this.discoveryClient;
}


package com.tedu.java;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* @author 47132
*/
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class PayMentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PayMentMain8001.class,args);
}
}
先要启动EurekaServer,再启动8001主启动类,需要稍等一会。在浏览器输入http://localhost:8001/payment/discovery

概述:
保护模式主要用于一组客户端和Erueka Server之间存在网络分区场景下的保护。一旦进入保护模式,Eureka Server 将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据,也就是不会注销任何微服务。
如果在Eureka Server的首页看到以下这段提示,则说明Eureka进入了保护模式:
EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN
THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES
ARE NOT BEING EXPIRED JUST TO BE SAFE.

出产默认,自我保护机制是开启的:eureka.server.enable-self-preservation=true,使用eureka.server.enable-self-preservation=false 可以禁用自我保护模式。

在默认情况下:
#Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
eureka.instance.lease-renewal-interval-in-seconds=30
#Eureka服务端在收到最后一次心跳后等待时间上限 ,单位为秒(默认是90秒),超时剔除服务
eureka.instance.lease-expiration-duration-in-seconds=90
配置:
eureka:
client:
#表示是否将自己注册进eurekaServer,默认为true
register-with-eureka: true
#是否从eurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须为true,才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/ #集群版
#defaultZone: http://eureka7001.com:7001/eureka
instance:
instance-id: payment8001
##Eureka服务端在收到最后一次心跳后等待时间上限 ,单位为秒(默认是90秒),超时剔除服务
lease-expiration-duration-in-seconds: 2
##Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)
lease-renewal-interval-in-seconds: 1

先启动EurekaServer,再启动8001,先关闭8001,看是否被删除。


Eureka停止更新了,你怎么办?
网址:https://github.com/Netflix/eureka/wiki

Zookeeper是一个分布式协调工具,可以实现注册中心功能。
关闭Linux服务器防火墙后启动Zookeeper服务器。
cloud2022
com.tedu.java
1.0-SNAPSHOT
4.0.0
cloud-provider-payment8004
com.tedu.java
cloud-api-commons
1.0-SNAPSHOT
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-zookeeper-discovery
org.springframework.boot
spring-boot-starter-actuator
org.projectlombok
lombok
org.springframework.boot
spring-boot-devtools
runtime
true
#8004表示注册到zookeeper服务器的支付服务提供者端口号
server:
port: 8004
spring:
application:
name: cloud-provider-payment
cloud:
zookeeper:
connect-string: 192.168.43.128:2181
package com.tedu.java;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @author 47132
*/
@SpringBootApplication
//该注解用于向使用consul或者zookeeper作为注册中心时注册服务
@EnableDiscoveryClient
public class PaymentMain8004 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8004.class,args);
}
}
package com.tedu.java.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
@RestController
@Slf4j
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping("/payment/zk")
public String paymentZk(){
return "SpringCloud with Zookeeper:"+serverPort+"\t"+ UUID.randomUUID().toString();
}
}
启动zk:
zkServer.sh start
启动后问题:

解决zookeeper版本jar包冲突问题:

排除zk冲突后的新POM:
cloud2022
com.tedu.java
1.0-SNAPSHOT
4.0.0
cloud-provider-payment8004
com.tedu.java
cloud-api-commons
1.0-SNAPSHOT
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-zookeeper-discovery
org.apache.zookeeper
zookeeper
org.apache.zookeeper
zookeeper
3.7.1
org.springframework.boot
spring-boot-starter-actuator
org.projectlombok
lombok
org.springframework.boot
spring-boot-devtools
runtime
true
http://localhost:8004/payment/zk

获得json串后用在线工具查看试试?


临时节点

cloud2022
com.tedu.java
1.0-SNAPSHOT
4.0.0
cloud-consumerzk-order80
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-actuator
org.springframework.cloud
spring-cloud-starter-zookeeper-discovery
org.apache.zookeeper
zookeeper
org.apache.zookeeper
zookeeper
3.7.1
org.springframework.boot
spring-boot-starter-test
com.tedu.java
cloud-api-commons
1.0-SNAPSHOT
org.projectlombok
lombok
#80表示注册到zookeeper服务器的支付服务提供者端口号
server:
port: 80
spring:
application:
name: cloud-consumerzk-order
cloud:
zookeeper:
connect-string: 192.168.43.128:2181
package com.tedu.java;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class OrderZkMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderZkMain80.class,args);
}
}
配置bean:ApplicationContextConfig
package com.tedu.java.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
controller:OrderZkController
package com.tedu.java.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class OrderZkController {
private static final String INVOKE_URL="http://cloud-provider-payment";
@Autowired
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/zk")
public String paymentInfo() {
return restTemplate.getForObject(INVOKE_URL + "/payment/zk", String.class);
}
}
http://localhost/consumer/payment/zk

官网地址:https://www.consul.io/intro/index.html
HashiCorp Consul是一个服务网络解决方案,它使团队能够管理服务之间以及跨on-prem和多云环境和运行时的安全网络连接。Consul提供服务发现、服务网格、流量管理和对网络基础设施设备的自动更新。您可以单独使用这些功能,也可以在单个Consul部署中一起使用这些功能。


下载地址:https://www.consul.io/downloads.html
文档地址:https://www.springcloud.cc/spring-cloud-consul.html
地址:https://learn.hashicorp.com/consul/getting-started/install.html
下载完成后只有一个consul.exe文件 硬盘路径下双击运行,查看版本信息:
consul -version

consul agent -dev

通过以下地址可以访问Consul的首页: http://localhost:8500;

cloud2022
com.tedu.java
1.0-SNAPSHOT
4.0.0
cloud-providerconsul-payment8006
org.springframework.cloud
spring-cloud-starter-consul-discovery
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-starter-test
com.tedu.java
cloud-api-commons
1.0-SNAPSHOT
org.projectlombok
lombok
org.springframework.boot
spring-boot-devtools
###consul服务端口号
server:
port: 8006
spring:
application:
name: consul-provider-payment
###consul注册中心地址
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
hostname: 127.0.0.1
package com.tedu.java;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain8006 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8006.class,args);
}
}
package com.tedu.java.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
/**
* @author 47132
*/
@RestController
@Slf4j
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@RequestMapping(value = "payment/consul")
public String paymentConsul() {
return "SpringCloud with consul:" + serverPort + "\t" + UUID.randomUUID().toString();
}
}
http://localhost:8006/payment/consul

cloud-consumerconsul-order80
cloud2022
com.tedu.java
1.0-SNAPSHOT
4.0.0
cloud-consumerconsul-order80
org.springframework.cloud
spring-cloud-starter-consul-discovery
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-starter-test
com.tedu.java
cloud-api-commons
1.0-SNAPSHOT
org.projectlombok
lombok
org.springframework.boot
spring-boot-devtools
###consul服务端口号
server:
port: 80
spring:
application:
name: cloud-consumer-order
###consul注册中心地址
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
hostname: 127.0.0.1
package com.tedu.java;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class OrderConsulMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderConsulMain80.class,args);
}
}
package com.tedu.java.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @author 47132
*/
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemple(){
return new RestTemplate();
}
}
package com.tedu.java.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@Slf4j
public class OrderConsulController {
private static final String INVOKE_URL = "http://consul-provider-payment";
@Autowired
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/consul")
public String paymentInfo(){
String template = restTemplate.getForObject(INVOKE_URL + "/payment/consul", String.class);
return template;
}
}
访问地址:http://localhost/consumer/payment/consul





