概述
搭建Eureka集群环境
目的:负载均衡、故障容错
如果我们只配置一个Eureka服务端,那么如果这个服务端崩盘,那么所有服务都无法获取,这肯定不是我们不期望的。所以为了保证高可用性,我们需要搭建Eureka集群。
新建子工程cloud-eureka-server7002 ,跟7001子工程一样,只有启动类和yml文件不一致
-
打开 本地 C:WindowsSystem32driversetchosts 文件
在最后一行添加如图所示 信息
-
cloud-eureka-server7002.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.atguigu.springcloud</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.atguigu.springcloud</groupId> <artifactId>cloud-eureka-server7002</artifactId> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>com.atguigu.springcloud</groupId> <artifactId>cloud-api-commons</artifactId> <version>${project.version}</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-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
-
application.yml
-
server: port: 7002 #eureka服务端的实例名称 eureka: instance: hostname: eureka7002.com client: #false表示不向注册中心注册自己 register-with-eureka: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去搜索服务 fetch-registry: false service-url: #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址 # defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ defaultZone: http://eureka7001.com:7001/eureka/
启动类EurekaMain7002.java
-
package com.atguigu.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication @EnableEurekaServer public class EurekaMain7002 { public static void main(String[] args) { SpringApplication.run(EurekaMain7002.class,args); } }
最后修改子工程cloud-eureka-server7001的yml文件
-
server: port: 7001 #eureka服务端的实例名称 eureka: instance: hostname: eureka7001.com client: #false表示不向注册中心注册自己 register-with-eureka: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去搜索服务 fetch-registry: false service-url: #设置与eureka server交互的地址查询服务和注册服务都需要依赖这个地址 # defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ defaultZone: http://eureka7002.com:7002/eureka/
启动子工程 7001 和 7002
分别访问 http://eureka7001.com:7001/ 和 http://eureka7002.com:7002/
-
支付Payment8001和订单order80 子工程注册进eureka 7001 和 eureka7002中
子工程payment8001的yml文件
-
server: port: 8001 spring: application: name: cloud-payment-service #服务名 datasource: type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型 driver-class-name: com.mysql.cj.jdbc.Driver #数据库驱动包 url: jdbc:mysql://localhost:3306/cloud2020?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true username: root password: root devtools: restart: enabled: true #是否支持热部署 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/erueka mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.atguigu.springcloud.entities #所有entity别名所在包
子工程order80的yml文件
-
server: port: 80 spring: application: name: cloud-order-service eureka: client: #表示是否将自己注册进eurekaServer 默认为true register-with-eureka: true fetch-registry: true service-url: defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/erueka
启动测试:先启动eureka7001工程和eureka7002工程,再启动payment8001工程,最后启动order80工程
Postman访问: http://localhost:80/consumer/payment/get/3 成功
支付Payment8002子工程集群搭建,新建cloud-provider-payment8002子工程
cloud-provider-payment8002.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.atguigu.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.atguigu.springcloud</groupId>
<artifactId>cloud-provider-payment8002</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>com.atguigu.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
</project>
application.yml
server:
port: 8002
spring:
application:
name: cloud-payment-service #服务名
datasource:
type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型
driver-class-name: com.mysql.cj.jdbc.Driver #数据库驱动包
url: jdbc:mysql://localhost:3306/cloud2020?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
username: root
password: root
devtools:
restart:
enabled: true #是否支持热部署
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/erueka
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.atguigu.springcloud.entities #所有entity别名所在包
启动类PaymentMain8002.java
package com.atguigu.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class PaymentMain8002 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8002.class,args);
}
}
业务类完全一样,从payment8001子工程复制到payment8002子工程
同理,右键打开子工程payment8001的controller所在目录
修改Payment8001子工程和Payment8002子工程的controller文件,两个文件修改内容一样,加入引入application.yml的端口,使用@Value注解来引入
@Value("${server.port}")
private String serverPort;
Payment8001子工程的controller:
package com.atguigu.springcloud.controller;
import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import com.atguigu.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@Slf4j
@RestController
@RequestMapping("/payment")
public class PaymentController {
@Resource
private PaymentService paymentService;
@Value("${server.port}")
private String serverPort;
@PostMapping(value = "/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,"插入数据库失败",null);
}
}
//通过id进行查询
@GetMapping("/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id ){
Payment payment = paymentService.getPaymentById(id);
log.info("****查询结果:"+payment);
if (payment != null){
return new CommonResult(200,"查询成功,端口号为:"+serverPort,payment);
}else {
return new CommonResult(444,"没有对应记录,查询ID:"+id,null);
}
}
}
Payment8002子工程的controller
package com.atguigu.springcloud.controller;
import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import com.atguigu.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@Slf4j
@RestController
@RequestMapping("/payment")
public class PaymentController {
@Resource
private PaymentService paymentService;
@Value("${server.port}")
private String serverPort;
@PostMapping(value = "/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,"插入数据库失败",null);
}
}
//通过id进行查询
@GetMapping("/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id ){
Payment payment = paymentService.getPaymentById(id);
log.info("****查询结果:"+payment);
if (payment != null){
return new CommonResult(200,"查询成功,端口号为:"+serverPort,payment);
}else {
return new CommonResult(444,"没有对应记录,查询ID:"+id,null);
}
}
}
修改order80子工程的OrderController.java,把url改成eureka上的服务名
package com.atguigu.springcloud.controller;
import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
@RestController
@Slf4j
public class OrderController {
// private final static String PAYMENT_URL = "http://localhost:8001";
private final static String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
@Autowired
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id) {
log.info("****开始查询");
return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
}
@GetMapping("/consumer/payment/create")
public CommonResult<Payment> create(Payment payment) {
log.info("****开始新增");
return restTemplate.postForObject(PAYMENT_URL+"/payment/create",payment,CommonResult.class);
}
}
服务启动:eureka7001->eureka7002->payment8001->payment8002->order80
此时访问 http://localhost:80/consumer/payment/get/1 报500错误
There was an unexpected error (type=Internal Server Error, status=500).
I/O error on GET request for "http://CLOUD-PAYMENT-SERVICE/payment/get/1": CLOUD-PAYMENT-SERVICE; nested exception is java.net.UnknownHostException: CLOUD-PAYMENT-SERVICE
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://CLOUD-PAYMENT-SERVICE/payment/get/1": CLOUD-PAYMENT-SERVICE; nested exception is java.net.UnknownHostException: CLOUD-PAYMENT-SERVICE
因为我们配置了服务名访问,但是消费者不知道需要从哪台服务访问,需要在o上加入RestTemplate上加入@LoadBalanced开启负载均衡,默认会以轮训的方式加载每一台服务
在order80子工程的config下的ApplicationContextController.java中添加注解
package com.atguigu.springcloud.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();
}
}
之后多次访问postman http://localhost:80/consumer/payment/get/1 ,会依次出现不同的端口号
最后
以上就是无语大侠为你收集整理的Springcloud Alibaba详细入门教程(四)的全部内容,希望文章能够帮你解决Springcloud Alibaba详细入门教程(四)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复