eureka与zookeeper同样都可以作为spring cloud的注册组件,但考虑到分布式领域的CAP理论、C(Consistency数据一致性),A(Availability服务可用性)、P(Partition Tolerance分区容错性)由于C与A不能共存
在保证用户可用的基本前提下,eureka就显得比zookeeper更加适合作为注册中心
下面先来创建一个聚合工程
表的信息
先创建服务的提供者provider
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">
<modelVersion>4.0.0</modelVersion>
<artifactId>service-provider</artifactId>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
</parent>
<dependencies>
<!-- Add typical dependencies for a web application -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>3.3.9</version>
</dependency>
</dependencies>
</project>
yml文件
server:
port: 8082
sessionTimeout: 20
servlet:
context-path: /provider
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url : jdbc:mysql://localhost:3306/ampmysql?serverTimezone=GMT%2B8
username : root
password : 123
max-active: 1
max-idle: 1
min-idle: 0
#logging:
# config: classpath:config/logback.xml
#
#mybatis:
# mapper-locations: classpath:mappers/*.xml
#显示jpa的执行sql
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
实体类pojo
import lombok.Data;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
@Data
@Table(name="bookinfo")
public class BookInfo implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;
private String title;
private String author;
}
映射mapper
import com.flash.pojo.BookInfo;
import tk.mybatis.mapper.common.Mapper;
@org.apache.ibatis.annotations.Mapper
public interface BookInfoMapper extends Mapper<BookInfo> {
}
service接口
import com.flash.pojo.BookInfo;
public interface BookInfoService {
public BookInfo findById(int id);
}
接口实现类
import com.flash.mapper.BookInfoMapper;
import com.flash.pojo.BookInfo;
import com.flash.service.BookInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class BookInfoServiceImpl implements BookInfoService {
@Resource
private BookInfoMapper bookInfoMapper;
@Override
public BookInfo findById(int id) {
return bookInfoMapper.selectByPrimaryKey(id);
}
}
controller层
import com.flash.pojo.BookInfo;
import com.flash.service.impl.BookInfoServiceImpl;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class BookInfoController {
@Resource
private BookInfoServiceImpl bookInfoServiceImpl;
@RequestMapping("/findById/{id}")
public BookInfo findById(@PathVariable(name="id") int id){
return bookInfoServiceImpl.findById(id);
}
}
启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tk.mybatis.spring.annotation.MapperScan;
@SpringBootApplication
@MapperScan(basePackages = "com.flash.mapper")
public class ProviderApp {
public static void main(String[] args) {
SpringApplication.run(ProviderApp.class,args);
}
}
再来创建服务的消费者consumer
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">
<modelVersion>4.0.0</modelVersion>
<artifactId>server-consumer</artifactId>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
pojo类,service层基本一致
import lombok.Data;
@Data
public class BookInfo {
private String id;
private String title;
private String author;
}
import com.flash.pojo.BookInfo;
public interface BookInfoService {
public BookInfo findById(int id);
}
接口实现
import com.flash.pojo.BookInfo;
import com.flash.service.BookInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.awt.print.Book;
@Service
public class BookInfoServiceImpl implements BookInfoService {
@Autowired
private RestTemplate restTemplate;
@Override
public BookInfo findById(int id) {
BookInfo bookInfo =
restTemplate.getForObject("http://localhost:8081/provider/findById/"+id,BookInfo.class);
System.out.println(bookInfo);
return bookInfo;
}
}
使用rest方式调用
测试类
import com.flash.ComsumerApp;
import com.flash.service.BookInfoService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
@RunWith(SpringRunner.class)
@SpringBootTest(classes= ComsumerApp.class)
public class Test01 {
@Resource
private BookInfoService bookInfoService;
@Test
public void test(){
bookInfoService.findById(1);
}
}
编写启动类ComsumerApp
启动提供者,然后测试
下面开始操作eureka
重新创建一个聚合工程
聚合工程的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">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>cloudparent</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>eureka-server</module>
<module>eureka-client-provider</module>
<module>eureka-client-consumer</module>
<module>eureka-client-provider02</module>
<module>cloud-feign</module>
</modules>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.RC1</spring-cloud.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-depndencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
<packaging>pom</packaging>这个地方不要错
创建注册中心eureka
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>cloudparent</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>eureka-server</artifactId>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
yml文件
server:
port: 8888
spring:
application:
name: eureka-server #注册中心命名
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8888/eureka
# server:
# enable-self-preservation: false#关闭自我保护模式
# eviction-interval-timer-in-ms: 1000扫描失效服务的间隔时间
编写启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekApp {
public static void main(String[] args) {
SpringApplication.run(EurekApp.class,args);
}
}
然后启动
编写启动类的代码与上面一样
除启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import tk.mybatis.spring.annotation.MapperScan;
@SpringBootApplication
@MapperScan(basePackages = "com.flash.mapper")
@EnableEurekaClient
public class ProviderApp {
public static void main(String[] args) {
SpringApplication.run(ProviderApp.class,args);
}
}
需要添加@EnableEurekaClient客户端注解
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>cloudparent</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>eureka-client-provider</artifactId>
<dependencies>
<!-- Add typical dependencies for a web application -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<!-- 加入actuator依赖后,应用启动后会创建一些基于Web的Endpoint -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>3.3.9</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
</dependencies>
</project>
yml文件
server:
port: 8081
sessionTimeout: 20
servlet:
context-path: /provider
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url : jdbc:mysql://localhost:3306/ampmysql?serverTimezone=GMT%2B8
username : root
password : 123
max-active: 1
max-idle: 1
min-idle: 0
application:
name: eureka-client-provider
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8888/eureka
# defaultZone: http://127.0.0.1:8888/eureka,http://127.0.0.1:8889/eureka
instance:
prefer-ip-address: true
ip-address: 127.0.0.1
然后启动
下面编写服务的消费者
消费者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>cloudparent</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>eureka-client-consumer</artifactId>
<dependencies>
<!-- Add typical dependencies for a web application -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<!-- 加入actuator依赖后,应用启动后会创建一些基于Web的Endpoint -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
</dependencies>
</project>
yml文件
server:
port: 8082
spring:
application:
name: eureka-client-consumer
eureka:
client:
service-url:
# defaultZone: ttp://127.0.0.1:8888/eureka,http://127.0.0.1:8889/eureka
defaultZone: http://127.0.0.1:8888/eureka
消费者的接口实现
package com.flash.service.impl;
import com.flash.pojo.BookInfo;
import com.flash.service.BookInfoService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.List;
@Service
public class BookInfoServiceImpl implements BookInfoService {
@Autowired
private RestTemplate restTemplate;
@Resource
DiscoveryClient discoveryClient;
@Override
public BookInfo findById(int id) {
BookInfo bookInfo =
restTemplate.getForObject("http://localhost:8081/provider/findById/"+id,BookInfo.class);
return bookInfo;
}
}
创建RestTemplateConfig配置类
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import com.netflix.loadbalancer.RetryRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
启动类
package com.flash;
import com.flash.config.RestTemplateConfig;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
@EnableEurekaClient //客户端
public class ConsumApp {
public static void main(String[] args) {
SpringApplication.run(ConsumApp.class,args);
}
}
启动
再次查看eureka页面信息
然后调用一把消费者
查看结果
ok!搞定收工