Eureka服务注册(已停更)
详情介绍就不多说,网上文档官网文档介绍很清楚,这里直接上代码。
创建maven父工程
<!-- 重点修改打包方式 pom-->
<packaging>pom</packaging>
<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.26</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>
什么不是服务注册?
-
在父工程中添加两个子工程分别是支付模块cloud-provider-payment8001和客户模块cloud-consumer-order80
-
支付模块配置
<artifactId>cloud-provider-payment8001</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.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <!--mysql-connector-java--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--jdbc--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</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> </dependencies>配置yml
server: port: 8001 spring: datasource: type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型 driver-class-name: com.mysql.cj.jdbc.Driver # mysql驱动包 url: jdbc:mysql://localhost:3306/cloud?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: root这里新建一个简单数据库就可,一个id,一个name,并配置mapper
@GetMapping("/payment/get/{id}") public Result getPayment(@PathVariable("id") Long id){ Payment Result = paymentService.getPaymentById(id); log.info("******查找结果"+Result+Result); if(Result != null){ return new Result(200,"查找成功); } return new Result(444,"查找失败"); }统一结果返回
public class Result<T> { private Integer code; private String message; private T data; public Result (Integer code,String message){ this(code,message,null); } } -
客户模块配置
artifactId>cloud-consumer-order80</artifactId> <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> </dependencies>server: port: 80配置RestTemplate,后面会详细解释
@Configuration public class ApplicationContextConfig { @Bean public RestTemplate getRestTemplate() { RestTemplate restTemplate = new RestTemplate(); restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));//乱码 return restTemplate; } }Controller,获得支付模块接口并调用
private static final String PAYMENT_URL = "http://localhost:8001"; @GetMapping("/consumer/get/{id}") public String getPaymentById(@PathVariable("id") Long id){ String result = restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id, String.class); return result; } -
测试
开启服务测试
成功调用
Eureka服务注册
-
新建服务注册中心模块cloud-eureka-server7001
<artifactId>cloud-eureka-server7001</artifactId> <dependencies> <!--eureka-server 这里一定是server表示注册中心--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <!--boot web actuator--> <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> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> </dependencies>yml配置
server: port: 7001 eureka: instance: hostname: eureka7001.com #eureka服务端的实例名称 client: register-with-eureka: false #false表示不向注册中心注册自己。 fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务 service-url: #单机 defaultZone: http://eureka7001.com:7001/eureka/启动类
@SpringBootApplication @EnableEurekaServer //开启服务中心 public class EurekaServer7001 { public static void main(String[] args) { SpringApplication.run(EurekaServer7001.class, args); } } -
配置服务端与客服端
pom都新增
<!-- 这里是 client --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>order80配置yml
spring: application: name: cloud-order-service eureka: client: #表示是否将自己注册进EurekaServer默认为true。 register-with-eureka: true #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡 fetchRegistry: true service-url: #单机 defaultZone: http://localhost:7001/eureka instance: instance-id: order80 # #访问路径可以显示IP地址 prefer-ip-address: true启动类
@SpringBootApplication @EnableEurekaClient //开启注册 public class MainOrder80 { public static void main(String[] args) { SpringApplication.run(MainOrder80.class,args); } }payment8001配置是一样的只需要改一下名字
-
测试
启动7001-》8001-》80
浏览器输入注册中心地址http://localhost:7001/
查看结果看到相应配置以及被注册进来的消费者生产者
这时候测试80端口接口还是行得通的。
-
集群
集群多个注册中心和多个服务业务,那么久多写出一个eureka7002当做集群控制中心,这里如果是在本地电脑操作,就要修改C:\Windows\System32\drivers\etc中hosts文件添加
127.0.0.1 eureka7002.com 127.0.0.1 eureka7001.comeureka7002配置和eureka7001差不多也可以直接复制修改名字,重点在于这两个注册中心也要互相注册,将指向本身的url指向要集群的url即可。
service-url: #集群指向其它eureka defaultZone: http://eureka7002.com:7002/eureka/多个支付模块集群配置几乎和payment8001几乎一样,注意点是application-name
cloud-payment-service ,还有一点就是现在有两个注册中心,需要同时注册进入两个注册中心用逗号隔开就好
service-url: #单机版 # defaultZone: http://localhost:7001/eureka # 集群版 defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka -
测试
这时调用80端口查询接口就有不同的效果。更改一下8001,8002Controller代码
@Value("${server.port}")
private String port;
@GetMapping("/payment/get/{id}")
public Result getPayment(@PathVariable("id") Long id){
Payment Result = paymentService.getPaymentById(id);
log.info("******查找结果"+Result+Result+"port"+port);
if(Result != null){
return new Result(200,"查找成功"+"port"+port,Result);
}
return new Result(444,"查找失败"+"port"+port);
}
更改80端口代码,本来80接口是写死查询8001。我们这里要改为注册中心暴露的端口CLOUD-PAYMENT-SERVICE也就是application-name。
// private static final String PAYMENT_URL = "http://localhost:8001";
private static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
修改配置类加入@LoadBalanced 赋予RestTemplate负载均衡的能力
@Configuration
public class ApplicationContextConfig
{
@Bean
@LoadBalanced
public RestTemplate getRestTemplate()
{
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
return restTemplate;
}
}
测试结果,看到结果我们会发现多发送请求就会访问不同的端口。说明我们已经成功了。
总结
- 这点对点的遍历中理解很简单,就模块之间的方法调用。但是如果服务很多用户量急剧增加,量变引起质变,怎么去判断有多少提供的服务,有多少客户?
- 那就用到eureka服务注册,管理服务于服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册。 哪还有一个问题就是注册中心程序崩了怎么办或者服务提供程序崩了怎么办?
-
这时就引出的集群概念,试想你的注册中心只有一个only one, 它出故障了那就完犊子谁也不认识谁老死不相往来,会导致整个为服务环境不可用,所以搭建Eureka注册中心集群 ,实现负载均衡+故障容错,而服务提供接口也是这个道理。
-
小知识点
- Eureka自我保护功能eureka.server.enable-self-preservation=true默认开启。
这个功能就是在服务可能停止运行之后不会直接将服务删除,而是默认应该是90秒删除,排除假死的可能。这种情况就相当于人停止心跳大脑不会直接死亡还有抢救的机会,假死现象不能放弃每一个病人。
eviction-interval-timer-in-ms: 2000 //设置假死时间
eureka.server.enable-self-preservation=true//开启关闭
- 发现payment8001、8002中有相同的实体类entities,所以我们将这个相同的实体类拿出来放入一个新模块cloud-api-commons中。
配置pom加入需要的
<dependencies>
<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>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.1.0</version>
</dependency>
</dependencies>
包结构最好和8001、8002一样。将cloud-api-commons通过maven打包。最好是先clean然后install
删除8001/8002中实体类包然后通过maven导入上面打好的包
<dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
<groupId>com.cloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>