1.创建一个project,然后把src目录删掉
2.修改pom.xml
<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.0modelVersion>
<groupId>org.tanggroupId>
<artifactId>springcloudartifactId>
<version>1.0-SNAPSHOTversion>
<modules>
<module>springcloud-apimodule>
<module>springcloud-provider-dept-8001module>
<module>springcloud-consumer-dept80module>
<module>springcloud-eureka-7001module>
modules>
<packaging>pompackaging>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<maven.compiler.source>1.8maven.compiler.source>
<maven.compiler.target>1.8maven.compiler.target>
<junit.version>4.12junit.version>
<log4j.version>1.2.17log4j.version>
<lombok.version>1.16.18lombok.version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-alibaba-dependenciesartifactId>
<version>0.2.0.RELEASEversion>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>Greenwich.SR1version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>2.1.4.RELEASEversion>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.47version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.10version>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>1.3.2version>
dependency>
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-coreartifactId>
<version>1.2.3version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>${junit.version}version>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>${log4j.version}version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>${lombok.version}version>
dependency>
dependencies>
dependencyManagement>
project>
3.创建module模块
创建springcloud-api,主要是实体类,跟数据库

pom.xml
<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>springcloudartifactId>
<groupId>org.tanggroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>springcloud-apiartifactId>
<dependencies>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
dependencies>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
properties>
project>
package com.tang.springcloud.pojo;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@NoArgsConstructor
@Accessors(chain = true) //链式写法
public class Dept implements Serializable {
// 实体类 orm-> 表
private Long deptno; //主键
private String dname;
//这个数据存在数据库的字段,微服务,一个服务对应一个数据库
private String db_source;
public Dept(Long deptno, String dname, String db_source) {
this.deptno = deptno;
this.dname = dname;
this.db_source = db_source;
}
/**
* 链式写法
* Dept dept = new Dept()
* dept.setDeptNo(11).setDname('ssss').setDb_source('001')
* */
}
4.创建provider,服务提供者
创建module模块,springcloud-provider-dept-8001
pom.xml
<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>springcloudartifactId>
<groupId>org.tanggroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>springcloud-provider-dept-8001artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-eureka-serverartifactId>
<version>1.4.6.RELEASEversion>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.dataformatgroupId>
<artifactId>jackson-dataformat-xmlartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.tanggroupId>
<artifactId>springcloud-apiartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
dependency>
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-coreartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-testartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jettyartifactId>
dependency>
dependencies>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
properties>
project>
server:
port: 8001
#mybaties 配置
#mybaties:
# type-aliases-package: com.tang.springcloud.pojo
# config-location: classpath:mybatis/mybatis-config.xml
# mapper-locations: classpath:mybatis/mapper/*.xml
#spring 配置
spring:
application:
name: springcloud-provider-dept
# datasource:
# type: com.alibaba.druid.pool.DruidDataSource
# driver-class-name: org.gjt.mm.mysql.Driver
# url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf-8
# username: root
# password: 123456
#Eureka配置
eureka:
instance:
instance-id: springcloud-provider-dept8001 #修改eureka上的默认描述信息
# hostname: provider8001 # Eureka服务端的实例名称
client:
service-url: #监控页面
# this.serviceUrl.put("defaultZone", "http://localhost:8761/eureka/");
# defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/
defaultZone: http://localhost:7001/eureka/
#info配置
info:
app.name: tangshen-springcloud
company.name: www.duxiaowei.com
package com.tang.springcloud.service;
import com.tang.springcloud.pojo.Dept;
import java.util.List;
public interface DeptService {
// public boolean addDept(Dept dept);
public Dept queryById(Long id);
// public List queryAll();
}
package com.tang.springcloud.service;
//import com.tang.springcloud.dao.DeptDao;
import com.tang.springcloud.pojo.Dept;
import lombok.experimental.Accessors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@Accessors(chain = true) //链式写法
public class DeptServiceImpl implements DeptService{
// @Autowired
// private DeptDao deptDao;
// @Override
// public boolean addDept(Dept dept) {
// return deptDao.addDept(dept);
// }
@Override
public Dept queryById(Long id) {
// 造一个对象
Dept dept = new Dept();
System.out.println("DeptServiceImpl");
dept.setDeptno(11L).setDname("duxiaowei").setDb_source("db_source");
return dept;
}
// @Override
// public List queryAll() {
// return deptDao.queryAll();
// }
}
package com.tang.springcloud.controller;
import com.tang.springcloud.pojo.Dept;
import com.tang.springcloud.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
//提供Restfu服务
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
//获取一些配置的信息,得到具体的微服务
@Autowired
private DiscoveryClient client;
@GetMapping("/dept/get/{id}")
public Dept get(@PathVariable("id") Long id) {
System.out.println("controller");
return deptService.queryById(id);
}
//注册进来的微服务,获取一些消息
@GetMapping("/dept/discovery")
public Object discovery(){
//获取微服务列表的清单
List<String> services = client.getServices();
System.out.println("discovery==> services"+ services);
//得到一个具体的微服务信息,通过具体的微服务id,applicationName
List<ServiceInstance> instances = client.getInstances("SPRINGCLOUD-PROVIDER-DEPT");
for (ServiceInstance instance : instances) {
System.out.println("----------------------------------------");
System.out.println(
instance.getHost()+"\t"+
instance.getPort()+"\t"+
instance.getUri()+"\t"+
instance.getServiceId()+"\t"
);
}
return this.client;
}
}
package com.tang.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
//启动类
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
@EnableEurekaClient //开启Eureka客户端注解,在服务启动后自动向注册中心注册服务
@EnableDiscoveryClient //服务发现
public class DeptProvider_8001 {
public static void main(String[] args) {
SpringApplication.run(DeptProvider_8001.class,args);
}
}
可以先关闭Eureka开关,启动,调用接口测试,接口服务是否可用
5.创建Eureka注册中心 ,springcloud-eureka-7001
pom.xml
<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>springcloudartifactId>
<groupId>org.tanggroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>springcloud-eureka-7001artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-eureka-serverartifactId>
<version>1.4.6.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
dependency>
dependencies>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
properties>
project>
server:
port: 7001
#Eureka
eureka:
instance:
hostname: localhost # Eureka服务端的实例名称
client:
register-with-eureka: false #标识是否想注册中心注册自己
fetch-registry: false #fetch-registry如果为false表示自己为注册中心
service-url: #监控页面
# this.serviceUrl.put("defaultZone", "http://localhost:8761/eureka/");
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
# defaultZone: http://localhost:7002/eureka/,http://localhost:7003/eureka/
package com.tang.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer //服务端的启动类,可以接受别人注册进来~
public class EurekaServer_7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaServer_7001.class,args);
}
}
测试
注册中心:http://localhost:7001/
服务提供者:http://localhost:8001/dept/discovery
6. 消费者,
pom.xml
<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>springcloudartifactId>
<groupId>org.tanggroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>springcloud-consumer-dept80artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-eureka-serverartifactId>
<version>1.4.6.RELEASEversion>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.dataformatgroupId>
<artifactId>jackson-dataformat-xmlartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.tanggroupId>
<artifactId>springcloud-apiartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
properties>
project>
server:
port: 80
#spring 配置,应用名
spring:
application:
name: springcloud-customer
#Eureka配置
eureka:
instance:
instance-id: springcloud-customer-dept80 #修改eureka上的默认描述信息
# hostname: provider8001 # Eureka服务端的实例名称
client:
service-url: #监控页面
# this.serviceUrl.put("defaultZone", "http://localhost:8761/eureka/");
# defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/
defaultZone: http://localhost:7001/eureka/
package com.tang.springcloud.controller;
import com.tang.springcloud.pojo.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class DeptConsumerController {
//理解:消费者,不应该有service层
//Restful,
// public ResponseEntity getForEntity(String url, Class responseType, Map uriVariables)
//使用RestTemplate访问restful接口非常的简单粗暴且无脑
//(url,requestMap,ResponseBean.class) 这三个参数分别代表
//REST请求地址,请求参数,Http响应转换 被 转换成的对象类型
@Autowired
private RestTemplate restTemplate;//提供多种便捷访问远程http服务的方法,简单的Restful服务模板
// private static final String REST_URL_PREFIX = "http://localhost:8001";
private static final String REST_URL_PREFIX = "http://localhost:8001";
@GetMapping("/customer/dept/get/{id}")
public Dept get(@PathVariable("id") Long id) {
System.out.println("consumer------");
System.out.println(REST_URL_PREFIX+"/dept/get/"+id);
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id,Dept.class);
}
}
package com.tang.springcloud.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ConfigBean {
//@Configuration = spring applicationContext.xml
// 配置bean
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
package com.tang.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient //开启Eureka客户端注解,在服务启动后自动向注册中心注册服务
public class DeptConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer_80.class,args);
}
}
测试

注册中心:提供服务注册和发现功能,维护了一张服务列表,登记了有哪些服务提供者,然后服务消费者每次请求这张登记表来进行服务调用。
服务提供者:提供服务的模块,需要把自己注册到注册中心。
服务消费者:从注册中心获取服务列表,向服务提供者请求服务。
因为服务提供者可能故障,所以设有保活机制—-心跳检测。
心跳:提供者定期发送消息向Eureka刷新自己的状态
服务提供者在启动时,会检测配置属性中的:eureka.client.register-with-erueka=true参数是否正确,事实上默认就是true。如果值确实为true,则会向EurekaServer发起一个Rest请求,并携带自己的元数据信息,Eureka Server会把这些信息保存到一个双层Map结构中。第一层Map的Key就是服务名称,第二层Map的key是服务的实例id。(第二层Map为了支持服务提供者多机集群)
修改Euraka配置文件,把EurekaServer自己也作为一个服务,向其他注册中心进行注册。
就是集群,水平扩展,在其他机器上部署注册中心,然后注册中心之间互相调用。出现单机故障时,存活的注册中心继续提供服务注册和发现功能。
在注册服务完成以后,服务提供者会维持一个心跳(定时向EurekaServer发起请求),告诉EurekaServer:“我还活着”。这个我们称为服务的续约(renew);
有些时候,我们的服务提供方并不一定会正常下线,可能因为内存溢出、网络故障等原因导致服务无法正常工作。Eureka Server需要将这样的服务剔除出服务列表。因此它会开启一个定时任务,每隔60秒对所有失效的服务(超过90秒未响应)进行剔除。
可以通过eureka.server.eviction-interval-timer-in-ms参数对其进行修改,单位是毫秒,生成环境不要修改。
这是触发了Eureka的自我保护机制。当一个服务未按时进行心跳续约时,Eureka会统计最近15分钟心跳失败的服务实例的比例是否超过了85%。在生产环境下,因为网络延迟等原因,心跳失败实例的比例很有可能超标,但是此时就把服务剔除列表并不妥当,因为服务可能没有宕机。Eureka就会把当前实例的注册信息保护起来,不予剔除。生产环境下这很有效,保证了大多数服务依然可用。
但是这给我们的开发带来了麻烦, 因此开发阶段我们都会关闭自我保护模式: