赞
踩
什么是服务治理?
Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务治理
在传统的rpc远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,所以需要使用服务治理,管理服务与服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册!什么是服务注册与发现
Eureka采用了CS的设计架构,Eureka Server 作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用 Eureka的客户端连接到 Eureka Server并维持心
跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个服务是否正常运行。
在服务注册与发现中,有一个注册中心,当服务器启动的时候,会把当前自己服务器的信息比如服务地址、通讯地址等以别名方式注册到注册中心上。另一方 (消费者|服务提供
者) ,以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地RPC调用。RPC远程调用框架核心设计思想: 在于注册中心,因为使用注册中心管理每个服务与
服务之间的一个依赖关系(服务治理概念)。在任何rpc远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址))
Eureka包含两个组件: Eureka Server和Eureka Client
Eureka Server提供服务注册服务:
各个微服务节点通过配置启动后,会在EurekaServer中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观看到。
EurekaClient通过注册中心进行访问:
是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robinm)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳默认周期为30秒。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除 (默认90秒)。
我们直接利用eureka搭建一个服务注册与发现的集群,实现一个微服务调用的的功能
- <!--统一管理jar包版本-->
- <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>
- <lombok.version>1.18.10</lombok.version>
- <log4j.version>1.2.12</log4j.version>
- <mysql.version>8.0.18</mysql.version>
- <druid.version>1.1.10</druid.version>
- <mybatis.spring.boot.version>1.3.2</mybatis.spring.boot.version>
- </properties>
-
- <!--子模块继承之后,提供作用:锁定版本+子module不用写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-->
- <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>
- <!--mysql-->
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>${mysql.version}</version>
- <scope>runtime</scope>
- </dependency>
- <!-- druid-->
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>druid-spring-boot-starter</artifactId>
- <version>${druid.version}</version>
- </dependency>
-
- <!--mybatis-->
- <dependency>
- <groupId>org.mybatis.spring.boot</groupId>
- <artifactId>mybatis-spring-boot-starter</artifactId>
- <version>${mybatis.spring.boot.version}</version>
- </dependency>
- <!--junit-->
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>${junit.version}</version>
- </dependency>
- <!--log4j-->
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>${log4j.version}</version>
- </dependency>
- </dependencies>
-
- </dependencyManagement>
(cloud-eureka-server7001、cloud-eureka-server7002、cloud-eureka-server7003)
主启动类:其他两个就不贴了
- @EnableEurekaServer //表示此项目是eureka的服务注册中心
- @SpringBootApplication
- public class EurekaMain7001 {
- public static void main(String[] args) {
- SpringApplication.run(EurekaMain7001.class, args);
- }
- }
pom.xml
- <dependencies>
- <!-- eureka-server -->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
- </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>
- </dependencies>
application.yml 另外两个就不贴了,改下port和defaultZone
- server:
- port: 7001
-
- eureka:
- instance:
- hostname: eureka7001.com #eureka服务端的实例名称
- client:
- #false表示不向注册中心注册自己(想注册也可以,不过没必要)
- register-with-eureka: false
- #false表示自己端就是注册中心,职责就是维护服务实例,并不需要去检索服务
- fetch-reapplication.ymlgistry: false
- service-url:
- #设置与eurekaServer交互的地址查询服务和注册服务都需要依赖这个地址 单机
- #defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
- #集群版 相互注册,相互守望
- defaultZone: http://eureka7002.com:7002/eureka/, http://eureka7003.com:7003/eureka/
-
- # defaultZone是固定写法,如果想自定义,需要按以下写法才行:
- # region: eureka-server
- # availability-zones:
- # eureka-server: server1,server2
- # service-url:
- # server1: http://eureka7002.com:7002/eureka/
- # server2: http://eureka7003.com:7003/eureka/
-
- server:
- #关闭自我保护,默认为true
- enable-self-preservation: false
- #心跳的间隔时间,单位毫秒
- eviction-interval-timer-in-ms: 2000
修改下hosts文件:
cloud-api-commons
包路径为:
com.cjian.springcloud.bean
- public class CommonResult<T> {
-
- private Integer code;
- private String message;
- private T data;
-
- public CommonResult(Integer code, String message, T data) {
- this.code = code;
- this.message = message;
- this.data = data;
- }
-
- public CommonResult(Integer code, String message){
- this(code, message, null);
- }
-
- public CommonResult() {
- }
-
- public Integer getCode() {
- return code;
- }
-
- public void setCode(Integer code) {
- this.code = code;
- }
-
- public String getMessage() {
- return message;
- }
-
- public void setMessage(String message) {
- this.message = message;
- }
-
- public T getData() {
- return data;
- }
-
- public void setData(T data) {
- this.data = data;
- }
- }
- public class Payment implements Serializable {
-
- private Long id;
- private String serial;
-
-
- public Long getId() {
- return id;
- }
-
- public void setId(Long id) {
- this.id = id;
- }
-
- public String getSerial() {
- return serial;
- }
-
- public void setSerial(String serial) {
- this.serial = serial;
- }
- }
cloud-provider-payment8001、cloud-provider-payment8002
- <dependencies>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
- </dependency>
- <dependency>
- <groupId>com.cjian.springloud</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.mybatis.spring.boot</groupId>
- <artifactId>mybatis-spring-boot-starter</artifactId>
- <version>1.3.2</version>
- </dependency>
-
- <!-- alibaba的druid数据库连接池 -->
- <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>
- <version>8.0.18</version>
- </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>
application.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 # mysql驱动包
- url: jdbc:mysql://127.0.0.1:3306/mysql?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
- username: root
- password: 123456
-
- mybatis:
- mapperLocations: classpath:mapper/*.xml
- type-aliases-package: com.cjian.springcloud.bean # 所有Entity别名类所在包
-
-
- eureka:
- client:
- register-with-eureka: true
- fetch-registry: true
- service-url:
- #defaultZone: http://localhost:7001/eureka
- defaultZone: http://eureka7001.com:7001/eureka,http://eureka7001.com:7002/eureka,http://eureka7001.com:7003/eureka
-
- instance:
- instance-id: payment8001
- prefer-ip-address: true #访问路径可以显示ip地址
-
- #Eureka客户端向服务端发送心跳的时间间隔,单位秒(默认30秒)
- lease-renewal-interval-in-seconds: 1
- #Eureka服务端在收到最后一次心跳后等待的时间上限,单位秒(默认90秒),超时剔除服务
- lease-expiration-duration-in-seconds: 2
包路径:com.cjian.springcloud
- @Mapper
- public interface PaymentDao {
-
- public int create(Payment payment);
-
- public Payment getPaymentById(@Param("id") Long id);
- }
- public interface PaymentService {
- public int create(Payment payment);
-
- public Payment getPaymentById(@Param("id") Long id);
- }
- @Service
- public class PaymentServiceImpl implements PaymentService {
- @Resource
- private PaymentDao paymentDao;
-
- public int create(Payment payment)
- {
- return paymentDao.create(payment);
- }
-
- public Payment getPaymentById(Long id)
- {
- return paymentDao.getPaymentById(id);
- }
- }
- @RestController
- public class PaymentController {
- @Resource
- private PaymentService paymentService;
-
- @Value("${server.port}")
- private String serverPort;
-
- @PostMapping(value = "/payment/create")
- public CommonResult create(@RequestBody Payment payment)
- {
- int result = paymentService.create(payment);
- System.out.println(("*****插入结果:" + result));
-
- if(result > 0)
- {
- return new CommonResult(200,"插入数据库成功,serverPort: "+serverPort,result);
- }else{
- return new CommonResult(444,"插入数据库失败",null);
- }
- }
-
- @GetMapping(value = "/payment/get/{id}")
- public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id)
- {
- Payment payment = paymentService.getPaymentById(id);
-
- if(payment != null)
- {
- return new CommonResult(200,"查询成功,serverPort: "+serverPort,payment);
- }else{
- return new CommonResult(444,"没有对应记录,查询ID: "+id,null);
- }
- }
- }
- <?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.cjian.springcloud.dao.PaymentDao">
-
- <resultMap id="BaseResultMap" type="com.cjian.springcloud.bean.Payment">
- <id column="id" property="id" jdbcType="BIGINT"/>
- <id column="serial" property="serial" jdbcType="VARCHAR"/>
- </resultMap>
-
- <insert id="create" parameterType="com.cjian.springcloud.bean.Payment" useGeneratedKeys="true" keyProperty="id">
- insert into payment(serial) values(#{serial});
- </insert>
- <select id="getPaymentById" parameterType="Long" resultMap="BaseResultMap">
- select * from payment where id=#{id};
- </select>
-
- </mapper>
主启动类:
这里
- @SpringBootApplication
- //@EnableEurekaClient 不加该注解也是可以的,下面分析eureka原理的时候再说
- public class PaymentMain001 {
- public static void main(String[] args) {
- SpringApplication.run(PaymentMain001.class, args);
- }
- }
建表sql:
- CREATE TABLE `payment`(
- `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
- `serial` varchar(200) DEFAULT '',
- PRIMARY KEY (id)
- )ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4
另一个服务提供者不做赘述~
cloud-consumer-order80
- <dependencies>
- <!-- eureka-client -->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
- </dependency>
- <dependency>
- <groupId>com.cjian.springloud</groupId>
- <artifactId>cloud-api-commons</artifactId>
- <version>1.0-SNAPSHOT</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>
- </dependencies>
- @Configuration
- public class ApplicationContextConfig {
- //往容器中添加一个RestTemplate
- //RestTemplate提供了多种便捷访问远程http访问的方法
- @Bean
- @LoadBalanced//开启负载均衡功能
- public RestTemplate restTemplate(){
- return new RestTemplate();
- }
- }
- @RestController
- public class OrderController {
-
- // public static final String PAYMENT_URL = "http://localhost:8001";
- public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
-
- @Resource
- private RestTemplate restTemplate;
-
- //因为浏览器只支持get请求,为了方便这里就用get
- @GetMapping("/consumer/payment/create")
- public CommonResult<Payment> create(Payment payment){
- System.out.println("********插入的数据:" + payment);
- //postForObject分别有三个参数:请求地址,请求参数,返回的对象类型
- return restTemplate.postForObject(PAYMENT_URL + "/payment/create", payment, CommonResult.class);
- }
-
- @GetMapping("/consumer/payment/get/{id}")
- public CommonResult<Payment> getPayment(@PathVariable("id") Long id){
- System.out.println("********查询的id:" + id);
- //getForObject两个参数:请求地址,返回的对象类型
- return restTemplate.getForObject(PAYMENT_URL + "/payment/get/" + id, CommonResult.class);
- }
-
- }
application.yml
- #访问一个网站时,默认是80端口,给用户80端口,用户就可以不用加端口直接访问页面
- server:
- port: 81
-
- spring:
- application:
- name: cloud-order-service
-
- eureka:
- client:
- register-with-eureka: true
- etch-registry: true
- service-url:
- #defaultZone: http://localhost:7001/eureka
- defaultZone: http://eureka7001.com:7001/eureka,http://eureka7001.com:7002/eureka,http://eureka7001.com:7003/eureka
-
- instance:
- instance-id: consumer81
- prefer-ip-address: true #访问路径可以显示ip地址
-
- #Eureka客户端向服务端发送心跳的时间间隔,单位秒(默认30秒)
- lease-renewal-interval-in-seconds: 1
- #Eureka服务端在收到最后一次心跳后等待的时间上限,单位秒(默认90秒),超时剔除服务
- lease-expiration-duration-in-seconds: 2
主启动类:
- @SpringBootApplication
- //@EnableDiscoveryClient
- public class OrderMain80 {
- public static void main(String[] args) {
- SpringApplication.run(OrderMain80.class, args);
- }
- }
依次启动3个注册中心、消费者和2个服务提供者,访问 localhost:7001
访问 http://localhost:81/consumer/payment/get/3
再次访问:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。