SpringCloud微服务项目总结
1、创建一个maven工程父项目 microservice-cloud-01
2、创建实体类,工具类子项目 microservice-cloud-02-api
3、创建多个服务者项目 microservice-cloud-03-provid-8001 microservice-cloud-03-provid-hystrix-8002(或者更多个服务者项目)
4、创建多个消费者项目 microservice-cloud-04-consumer-product-80 microservice-cloud-04-consumer-product-fegin-80
5、创建至少两个注册中心maven项目 microservice-cloud-05-eureka-6001 microservice-cloud-05-eureka-6002
6、创建路由网关项目
1、创建一个maven工程父项目 microservice-cloud-01
父工程创建的目的:统一管理jar包依赖文件。整合项目为一个项目。
import
pom.xml文件
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">
4.0.0
cn.kgc
microservice-cloud-01
pom
1.0-SNAPSHOT
../microservice-cloud-02-api
../microservice-cloud-03-provider-product-8001
../microservice-cloud-04-consumer-product-80
../microservice-cloud-05-eureka-6001
../microservice-cloud-05-eureka-6002
../microservice-cloud-04-consumer-product-fegin
../microservice-cloud-03-provider-product-hystrix-8001
../microservice-cloud-9-zuul-getway-7001
org.springframework.boot
spring-boot-starter-parent
2.0.7.RELEASE
UTF-8
1.8
1.8
4.12
Finchley.SR2
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.2
com.alibaba
druid
1.1.12
mysql
mysql-connector-java
8.0.13
junit
junit
${junit.version}
test
2、创建实体类,工具类子项目 microservice-cloud-02-api
该项目放置实体类及工具类,其服务者和消费者都应该依赖于该项目,以便在实体类中存取数据,和使用工具类
其实体类要实现序列化接口Serializable接口,以便于在不同项目中通过网络调用
pom.xml文件
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">
microservice-cloud-01 cn.kgc 1.0-SNAPSHOT ../microservice-cloud-01/pom.xml 4.0.0 cn.kgc microservice-cloud-02-api 1.8 1.8
实体类Product
其实体类要实现序列化接口Serializable接口,以便于在不同项目中通过网络调用
其属性名为驼峰命名规则,应与数据库字段名一一对应
其所在包为: cn.kgc.springcloud.entity;
package cn.kgc.springcloud.entity; import java.io.Serializable; public class Product implements Serializable { private long pid; private String productName; private String dbSource; public Product() { } public Product(long pid, String productName, String dbSource) { this.pid = pid; //数据库字段名为pid this.productName = productName; //数据库字段名为product_name this.dbSource = dbSource; //数据库字段名为db_source } public long getPid() { return pid; } public void setPid(long pid) { this.pid = pid; } public String getProductName() { return productName; } public void setProductName(String productName) { this.productName = productName; } public String getDbSource() { return dbSource; } public void setDbSource(String dbSource) { this.dbSource = dbSource; } }
3、创建多个服务者项目 microservice-cloud-03-provid-8001 microservice-cloud-03-provid-hystrix-8002(或者更多个服务者项目)
3.1普通服务者项目microservice-cloud-03-provid-8001
3.1.1pom.xml文件
microservice-cloud-01 cn.kgc 1.0-SNAPSHOT ../microservice-cloud-01/pom.xml 4.0.0 cn.kgc microservice-cloud-03-provider-product-8001 1.8 1.8 cn.kgc microservice-cloud-02-api 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test org.mybatis.spring.boot mybatis-spring-boot-starter com.alibaba druid mysql mysql-connector-java junit junit org.springframework.cloud spring-cloud-starter-netflix-eureka-client
org.springframeeork.boot
spring-boot-starter-actuactor
3.1.2创建application.yml文件
路径resources.application.yml
注意:数据库驱动包的版本以确定驱动包的路径
数据库所在的IP地址以及数据库名是否正确
server: port: 8001 #设置端口号 mybatis: config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路径 type-aliases-package: cn.kgc.springcloud.entity # 所有Entity别名类所在包 mapper-locations: classpath:mybatis/mapper/**/*.xml # mapper映射文件 spring: application: name: microservice-product #这个很重要,这在以后的服务与服务之间相互调用一般都是根据这个name datasource: type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型 driver-class-name: com.mysql.cj.jdbc.Driver # mysql驱动包,com.mysql.jdbc.Driver 这个路径的驱动包版本比较低 url: jdbc:mysql://localhost:3306/springcloud_db01?serverTimezone=GMT%2B8 # 数据库名称,连接数据库 username: root #数据库账号 password: root #数据库密码 dbcp2: min-idle: 5 # 数据库连接池的最小维持连接数 initial-size: 5 # 初始化连接数 max-total: 5 # 最大连接数 max-wait-millis: 150 # 等待连接获取的最大超时时间 eureka: #向注册中心服务注册的配置 client: registerWithEureka: true #服务注册开关 fetchRegistry: true #服务发现开关 serviceUrl: # 集群版 Eureka defaultZone: http://eureka6001.com:6001/eureka/,http://eureka6002.com:6002/eureka/ # 两个注册中心的访问地址,用于服务者分别注册进两个注册中心 instance: instanceID: ${spring.application.name}:${server.port} # 指定实例ID 不显示主机名 preferIpAddress: true
3.1.3创建mybatis.cfg.xml文件
路径:resource.mybatis.mybatis.cfg.xml
该文件用于设置驼峰命名规则,以便程序与实体类之间的可以映射上
DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
3.1.4创建ProductMapper.xml
路径为:resources.mybatis.mapper.ProductMapper.xml
该文件为mapper接口的映射文件,用于写sql语句
namespace="mapper接口所在的包全路径"
id为mapper接口的方法名。 resultType为mapper接口的返回值类型。 parameterType为参数的数据类型
INSERT INTO product(product_name,db_source) VALUES(#{productName},#{dbSource})
3.1.5创建mappe接口
路径:cn.kgc.springcloud.mapper.ProductMapper.class
@Mapper注解//该注解用于程序扫描mapper包,与启动类的@MapperScan注解作用一样,启动类标注@MapperScan注解口,则可以省略
package cn.kgc.springcloud.mapper; import cn.kgc.springcloud.entity.Product; import java.util.List; //@Mapper//该注解用于程序扫描到mapper包,等同于在启动类中的@MappearScan(cn.kgc) public interface ProductMapper { //获得所有产品 ListfindAll(); //通过id查询产品 Product findById(Long pid); //添加一条产品信息 boolean addProduct(Product product); }
3.1.6service接口及实现类
service接口
package cn.kgc.springcloud.service; import cn.kgc.springcloud.entity.Product; import java.util.List; public interface ProductService { //获得所有产品 ListfindAll(); //通过id查询产品 Product findById(Long pid); //添加一条产品信息 boolean addProduct(Product product); }
service实现类
package cn.kgc.springcloud.service.impl; import cn.kgc.springcloud.entity.Product; import cn.kgc.springcloud.mapper.ProductMapper; import cn.kgc.springcloud.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class ProductServiceImpl implements ProductService { @Autowired private ProductMapper productMapper; @Override public ListfindAll() { return productMapper.findAll(); } @Override public Product findById(Long pid) { return productMapper.findById(pid); } @Override public boolean addProduct(Product product) { return productMapper.addProduct(product); } }
3.1.7创建controller层
package cn.kgc.springcloud.controller; import cn.kgc.springcloud.entity.Product; import cn.kgc.springcloud.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class ProductController { @Autowired private ProductService productService; @RequestMapping(value = "/product/get/list",method = RequestMethod.GET) public ListgetfindAll(){ List productList = productService.findAll(); return productList; } @RequestMapping(value = "/product/findById/{id}",method = RequestMethod.GET) public Product findById(@PathVariable("id") Long id) { return productService.findById(id); } @RequestMapping(value = "/product/add",method = RequestMethod.GET) public String addProduct(Product product){ boolean b = productService.addProduct(product); if(b){ return "数据保存成功!"; }else { return "数据保存失败!"; } } }
3.1.8创建启动类
注解:
@MapperScan("cn.kgc.springcloud.mapper")//该注解用于扫描mapper包,如果mapper接口已标注@Mapper注解则可以省略
package cn.kgc.springcloud; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @EnableEurekaClient//用于向注册中心服务注册 @SpringBootApplication//标注这是一个Springboot的启动类 @MapperScan("cn.kgc.springcloud.mapper")//用于扫描mapper包,如果mapper包的接口标注了@Mapper注解则可以省略 public class SpringcloudProduct { public static void main(String[] args) { SpringApplication.run(SpringcloudProduct.class,args); } }
3.2控制雪崩服务者项目microservice-cloud-03-provid-hystrix-8002
创建hystrix熔断器服务者项目
该项目也是服务者项目,并分别注册进两个注册中心
项目开发用hystrix熔断器方式,用于防止程序异常时出现的线程死锁问题,
3.2.1创建pom.xml文件
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"> microservice-cloud-01 cn.kgc 1.0-SNAPSHOT ../microservice-cloud-01/pom.xml 4.0.0 cn.kgc microservice-cloud-03-provider-product-hystrix-8001 1.8 1.8 cn.kgc microservice-cloud-02-api 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test org.mybatis.spring.boot mybatis-spring-boot-starter com.alibaba druid mysql mysql-connector-java junit junit org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.cloud spring-cloud-starter-netflix-hystrix
org.springframework.boot
spring-boot-starter-actuator
3.2.2创建application.yml文件
路径resources.application.yml
注意:数据库驱动包的版本以确定驱动包的路径
数据库所在的IP地址以及数据库名是否正确
server: port: 8001 #设置端口号 mybatis: config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路径 type-aliases-package: cn.kgc.springcloud.entity # 所有Entity别名类所在包 mapper-locations: classpath:mybatis/mapper/**/*.xml # mapper映射文件 spring: application: name: microservice-product #这个很重要,这在以后的服务与服务之间相互调用一般都是根据这个name datasource: type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型 driver-class-name: com.mysql.cj.jdbc.Driver # mysql驱动包,com.mysql.jdbc.Driver 这个路径的驱动包版本比较低 url: jdbc:mysql://localhost:3306/springcloud_db01?serverTimezone=GMT%2B8 # 数据库名称,连接数据库 username: root #数据库账号 password: root #数据库密码 dbcp2: min-idle: 5 # 数据库连接池的最小维持连接数 initial-size: 5 # 初始化连接数 max-total: 5 # 最大连接数 max-wait-millis: 150 # 等待连接获取的最大超时时间 eureka: #向注册中心服务注册的配置 client: registerWithEureka: true #服务注册开关 fetchRegistry: true #服务发现开关 serviceUrl: # 集群版 Eureka defaultZone: http://localhost:6001/eureka/,http://localhost:6002/eureka/ #分别注册进两个注册中心 instance: instanceID: ${spring.application.name}:${server.port} # 指定实例ID 不显示主机名 preferIpAddress: true
3.1.3创建mybatis.cfg.xml文件
路径:resource.mybatis.mybatis.cfg.xml
该文件用于设置驼峰命名规则,以便程序与实体类之间的可以映射上
DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
3.1.4创建ProductMapper.xml
路径为:resources.mybatis.mapper.ProductMapper.xml
该文件为mapper接口的映射文件,用于写sql语句
namespace="mapper接口所在的包全路径"
id为mapper接口的方法名。 resultType为mapper接口的返回值类型。 parameterType为参数的数据类型
INSERT INTO product(product_name,db_source) VALUES(#{productName},#{dbSource})
3.1.5创建mappe接口
路径:cn.kgc.springcloud.mapper.ProductMapper.class
@Mapper注解//该注解用于程序扫描mapper包,与启动类的@MapperScan注解作用一样,启动类标注@MapperScan注解口,则可以省略
package cn.kgc.springcloud.mapper; import cn.kgc.springcloud.entity.Product; import java.util.List; //@Mapper//该注解用于程序扫描到mapper包,等同于在启动类中的@MappearScan(cn.kgc) public interface ProductMapper { //获得所有产品 ListfindAll(); //通过id查询产品 Product findById(Long pid); //添加一条产品信息 boolean addProduct(Product product); }
3.16service接口
package cn.kgc.springcloud.service;
import cn.kgc.springcloud.entity.Product;
import java.util.List;
public interface ProductService {
//获得所有产品
List findAll();
//通过id查询产品
Product findById(Long pid);
//添加一条产品信息
boolean addProduct(Product product);
}
3.17service实现类
package cn.kgc.springcloud.service.impl; import cn.kgc.springcloud.entity.Product; import cn.kgc.springcloud.mapper.ProductMapper; import cn.kgc.springcloud.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class ProductServiceImpl implements ProductService { @Autowired private ProductMapper productMapper; @Override public ListfindAll() { return productMapper.findAll(); } @Override public Product findById(Long pid) { return productMapper.findById(pid); } @Override public boolean addProduct(Product product) { return productMapper.addProduct(product); } }
3.1.7创建controller层
在controller层实现hystrix熔断器的应用,以保证在程序出现异常时不会造成线程死锁,而造成的程序崩溃
@HystrixCommand(fallbackMethod = "getfallback")该注解在程序出现异常时,调取指定的方法getfallback();以保证程序运行。在pom.xml文件中需添加依赖
package cn.kgc.springcloud.controller; import cn.kgc.springcloud.entity.Product; import cn.kgc.springcloud.service.ProductService; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class ProductController { @Autowired private ProductService productService; @RequestMapping(value = "/product/get/list",method = RequestMethod.GET) public ListgetfindAll(){ List productList = productService.findAll(); return productList; } /** * @param id * @return * @HystrixCommand(fallbackMethod = "getfallback")。这个注解的意思为: * 标注在findById()方法上。当findById()方法出现异常时调用hystixGet方法进行处理, * 以便程序正常执行,不让线程出现阻塞的情况。 * fallbackMethod = "getfallback"属性是制定方法异常时调用的方法名 */ @HystrixCommand(fallbackMethod = "getfallback") @RequestMapping(value = "/product/findById/{id}",method = RequestMethod.GET) public Product findById(@PathVariable("id") Long id) { Product product = productService.findById(id); if(product==null){ throw new RuntimeException("Id"+id+"是无效的id"); } return product; } /** * 当findById()方法异常不能执行时,调用该方法。 * 该方法的返回值和参数必须与原方法一致 */ private Product getfallback(@PathVariable("id") Long id){ return new Product(id,"Id"+id+"是无效的id","无效的数据库"); } @RequestMapping(value = "/product/add",method = RequestMethod.GET) public String addProduct(Product product){ boolean b = productService.addProduct(product); if(b){ return "数据保存成功!"; }else { return "数据保存失败!"; } } }
3.1.8创建启动类
注解:
@MapperScan("cn.kgc.springcloud.mapper")//该注解用于扫描mapper包,如果mapper接口已标注@Mapper注解则可以省略
@EnableHystrix//开启Hystrix熔断机制的支持
@EnableEurekaClient//用于向注册中心注册服务
@SpringBootApplication//标注这是一个Springboot的启动类
package cn.kgc.springcloud; import org.mybatis.spring.annotation.MapperScan; 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; @EnableHystrix//开启Hystrix熔断机制的支持 @EnableEurekaClient//用于向注册中心服务注册 @SpringBootApplication//标注这是一个Springboot的启动类 @MapperScan("cn.kgc.springcloud.mapper")//用于扫描mapper包,如果mapper包的接口标注了@Mapper注解则可以省略 public class SpringcloudProduct_hystrix { public static void main(String[] args) { SpringApplication.run(SpringcloudProduct_hystrix.class,args); } }
4、创建多个消费者项目 microservice-cloud-04-consumer-product-80
使用RestTemplate的模板方式调取注册中心的服务程序
该方式一般不用
分别注册进两个注册中心
4.1.1pom.xml文件
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"> microservice-cloud-01 cn.kgc 1.0-SNAPSHOT ../microservice-cloud-01/pom.xml 4.0.0 cn.kgc microservice-cloud-04-consumer-product-80 1.8 1.8 cn.kgc microservice-cloud-02-api 1.0-SNAPSHOT compile org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-eureka-client
4.1.2创建mappe接口
路径:cn.kgc.springcloud.mapper.ProductMapper.class
注意:设置的端口号与服务端不同
server: port: 80 #设置端口号 eureka: #向注册中心服务注册的配置 client: registerWithEureka: false #服务注册开关 fetchRegistry: true #服务发现开关 serviceUrl: # 集群版 Eureka defaultZone: http://eureka6001.com:6001/eureka/,http://eureka6002.com:6002/eureka/ #分别注册进两个注册中心 instance: instanceID: ${spring.application.name}:${server.port} # 指定实例ID 不显示主机名 preferIpAddress: true
4.1.3创建configBean.java
这个类是向容器中添加RestTemplate组件,添加模板的类。
@LoadBalanced注解
表示这个RestTemplate开启负载均衡 在调用服务者提供的接口时 可以使用服务名称替代真实的IP 地址
@Bean
package cn.kgc.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 ConfigBean { // 向容器中添加RestTemplate 组件 直接该组件调用EREST接口 /** * @LoadBalanced注解 * 表示这个RestTemplate开启负载均衡 在调用服务者提供的接口时 可以使用服务名称替代真实的IP 地址 * @return */ @LoadBalanced @Bean public RestTemplate getRestTemplate(){ return new RestTemplate(); } }
4.1.4创建controller类
项目中的亮绿色的内容是服务者的注册中心的地址,一般用服务者application.yml文件 application:name:的属性名的大写
项目中大红色的路径为服务者controller层的访问路径,必须一致,否则访问不到
项目中的暗绿色为消费者端的访问路径。测试时用该路径
postForObject()的三个参数分别是1、服务端的访问全路径。2、所在方法的参数。3、所在方法的返回值的class对象
package cn.kgc.springcloud.controller; import cn.kgc.springcloud.entity.Product; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import java.util.List; @RestController public class ProductController_Consumer { // private static final String REST_URL_PREFIX="http://localhost:8001"; private static final String REST_URL_PREFIX="http://MICROSERVICE-PRODUCT"; @Autowired private RestTemplate restTemplate; @RequestMapping(value = "/consumer/product/add") public boolean add(@RequestBody Product product){ return restTemplate.postForObject(REST_URL_PREFIX+"/product/add",product,Boolean.class); } @RequestMapping(value = "/consumer/product/get/{id}") public Product get(@PathVariable("id") Long id) { return restTemplate.getForObject(REST_URL_PREFIX + "/product/findById/" + id, Product.class); } @RequestMapping(value = "/consumer/product/get/list") public Listlist() { return restTemplate.getForObject(REST_URL_PREFIX + "/product/get/list" , List.class); } }
4.1.5启动类
@EnableEurekaClient//用于向注册中心服务注册
@SpringBootApplication//这是一个springboot的启动类
package cn.kgc.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @EnableEurekaClient//用于向注册中心服务注册 @SpringBootApplication public class ProductConsumer_80 { public static void main(String[] args) { SpringApplication.run(ProductConsumer_80.class,args); } }
消费者服务microservice-cloud-04-consumer-product-fegin-80
使用fegin负载均衡调用服务者
实际项目开发用负载均衡方式,别且分别注册进两个注册中心
4.2.1pom.xml文件
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"> microservice-cloud-01 cn.kgc 1.0-SNAPSHOT ../microservice-cloud-01/pom.xml 4.0.0 cn.kgc microservice-cloud-04-consumer-product-fegin 1.8 1.8 cn.kgc microservice-cloud-02-api 1.0-SNAPSHOT compile org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.cloud spring-cloud-starter-openfeign
4.2.2创建application.yml文件
server: port: 80 #设置端口号 eureka: #向注册中心服务注册的配置 client: registerWithEureka: false #服务注册开关 fetchRegistry: true #服务发现开关 serviceUrl: # 集群版 Eureka defaultZone: http://eureka6001.com:6001/eureka/,http://eureka6002.com:6002/eureka/ # 分别注册进两个注册中心 instance: instanceID: ${spring.application.name}:${server.port} # 指定实例ID 不显示主机名 preferIpAddress: true
4.2.3创建service层接口
项目中红色的注解@FeignClient(value = "microservice-product"),其value属性值为服务端在注册中心的注册地址
项目中的亮绿色地址为服务端controller层的访问地址,其必须一致,否则访问不到
package cn.kgc.springcloud.Service; import cn.kgc.springcloud.entity.Product; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import java.util.List; @FeignClient(value = "microservice-product") public interface ProductfeginService { @RequestMapping(value = "/product/get/list",method = RequestMethod.GET) Listlist(); @RequestMapping(value = "/product/findById/{id}",method = RequestMethod.GET) Product get(@PathVariable("id") Long id); @RequestMapping(value = "/product/add",method = RequestMethod.POST) boolean add(Product product); }
创建service实现类
该实现类为客户端熔断器
当程序出现异常时调用该方法,避免线程阻塞而使程序崩溃
package cn.kgc.springcloud.Service; import cn.kgc.springcloud.entity.Product; import org.springframework.stereotype.Component; import java.util.List; /** * 这个类是客户端的熔断器类 */ @Component//添加对象到spring容器 public class ProductClientServiceFallBack implements ProductfeginService{ @Override public Listlist() { return null; } /**
*程序出现异常调去该方法
*/
@Override public Product get(Long id) { return new Product(id,"id="+id+"无数据-fegin&hystrix","无效的数据库"); } @Override public boolean add(Product product) { return false; } }
4.2.4创建controller层
项目中的亮绿色地址为消费端的访问地址
package cn.kgc.springcloud.controller; import cn.kgc.springcloud.Service.ProductfeginService; import cn.kgc.springcloud.entity.Product; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class ProductController_Fegin { @Autowired private ProductfeginService service; @RequestMapping(value = "/consumer/product/list") public Listlist() { return service.list(); } @RequestMapping(value = "/consumer/product/get/{id}") public Product get(@PathVariable("id") Long id) { return service.get(id); } @RequestMapping("/product/add") public boolean add(Product product){ return service.add(product); } }
4.2.5创建启动类
@EnableFeignClients(basePackages = "cn.kgc.springcloud")//扫描包,以保证程序可以执行到service层
@EnableEurekaClient//向注册中心注册服务,用于调去注册中心的服务
@SpringBootApplication//标注这是springboot启动类
package cn.kgc.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.openfeign.EnableFeignClients; @EnableFeignClients(basePackages = "cn.kgc.springcloud")//开启客户端熔断器 @EnableEurekaClient//开启eureka注册 @SpringBootApplication public class ProductConsumer_80_fegin { public static void main(String[] args) { SpringApplication.run(ProductConsumer_80_fegin.class,args); } }
5、创建至少两个注册中心maven项目 microservice-cloud-05-eureka-6001
一般情况下要创建两个以上的注册中心,并相互注册,以便在某个注册中心出现异常时还有其他注册中心可以使用
5.1.1pom.xml文件
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"> microservice-cloud-01 cn.kgc 1.0-SNAPSHOT ../microservice-cloud-01/pom.xml 4.0.0 cn.kgc microservice-cloud-05-eureka-6001 org.springframework.cloud spring-cloud-starter-netflix-eureka-server
5.1.2创建application.xml文件
server: port: 6001 eureka: instance: hostname: eureka6001.com server: enable-self-preservation: false # 禁用自我保护模式,仅在测试时使用4.3 client: registerWithEureka: false #服务注册开关 fetchRegistry: false #服务发现开关 serviceUrl: # 单机是配置自己 如果不配置默认端口是8761 #defaultZone: http://${eureka.istance.hostname}:${server.port}/eureka/ #集群版,将该注册中心注册到6002端口的服务中心,进行相互注册 defaultZone: http://eureka6002.com/eureka/
5.1.3创建启动类
@EnableEurekaServer//告诉springCloud框架这是一个服务注册中心项目package cn.kgc.springcloud;
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @EnableEurekaServer//告诉springCloud框架这是一个服务注册中心项目 @SpringBootApplication public class Eurekaserver_6001 { public static void main(String[] args) { SpringApplication.run(Eurekaserver_6001.class,args); } }
创建第二个注册中心microservice-cloud-05-eureka-6001
一般情况下要创建两个以上的注册中心,并相互注册,以便在某个注册中心出现异常时还有其他注册中心可以使用
5.2.1创建pom.xml文件
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"> microservice-cloud-01 cn.kgc 1.0-SNAPSHOT ../microservice-cloud-01/pom.xml 4.0.0 cn.kgc microservice-cloud-05-eureka-6002 org.springframework.cloud spring-cloud-starter-netflix-eureka-server
5.2.2创建application.yml文件
server: port: 6002 eureka: instance: hostname: eureka6002.com server: enable-self-preservation: false # 禁用自我保护模式,仅在测试时使用 client: #本身就是配置中心所以一下皆为false registerWithEureka: false #服务注册开关 fetchRegistry: false #服务发现开关 serviceUrl: # 单机是配置自己 如果不配置默认端口是8761 #defaultZone: http://${eureka.istance.hostname}:${server.port}/eureka/ #集群版,将该注册中心注册到6001端口的服务中心,进行相互注册 defaultZone: http://eureka6001.com:6001/eureka/
5.2.3创建启动类
@EnableEurekaServer//说明这是一个服务注册中心项目
@SpringBootApplication//说明这是Springboot的启动类
package cn.kgc.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @EnableEurekaServer//说明这是一个服务注册中心项目 @SpringBootApplication//说明这是Springboot的启动类 public class Eurekaserver_6002 { public static void main(String[] args) { SpringApplication.run(Eurekaserver_6002.class,args); } }
6、创建路由网关项目microservice-cloud-9-zuul-getway-7001
pom.xml文件
"1.0" encoding="UTF-8"?>"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"> microservice-cloud-01 cn.kgc 1.0-SNAPSHOT ../microservice-cloud-01/pom.xml 4.0.0 cn.kgc microservice-cloud-9-zuul-getway-7001 1.8 1.8 org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-zuul
添加核心jar包
org.springframework.cloud spring-cloud-starter-netflix-zuul
创建application.yml文件
server: port: 7001 spring: application: name: microservice-zuul-geteway eureka: client: registerWithEureka: true #服务注册开关 fetchRegistry: true #服务发现开关 serviceUrl: # 集群版 Eureka # defaultZone: http://localhost:6002/eureka,http://localhost:6001/eureka defaultZone: http://eureka6002.com:6002/eureka/,http://eureka6001.com:6001/eureka/ instance: instanceID: ${spring.application.name}:${server.port} # 指定实例ID 不显示主机名 preferIpAddress: true #访问路径可以显示ip 地址 zuul: #路由设计 routes: povider-product: # 路由的名称、名称任意 保持所有路由名称唯一 path: /product/** #访问路径 serviceId: microservice-product #注册中心服务提供者注册名 stripPrefix: false # 代理转发时 不去掉前缀
创建路由网管拦截类:
该类继承ZuulFilter
实现ZuulFiter的四个方法
package cn.lijun.springcloud.filter; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import java.io.IOException; /** * 该类为路由网关过滤器 */ @Component //将自己的对象注入到spring容器中 public class LoginFilter extends ZuulFilter { Logger logger=LoggerFactory.getLogger(getClass()); @Override //返回字符串类型的对象。在请求路由前调用 public String filterType() { return "pre"; } @Override //返回int类型值, 过滤器的执行的顺序 数据越小优先级越高 public int filterOrder() { return 1; } //判断过滤器是否执行,返回true,表示执行 @Override public boolean shouldFilter() { return true; } //自定义过滤器 @Override public Object run() throws ZuulException { RequestContext currentContext = RequestContext.getCurrentContext(); HttpServletRequest request = currentContext.getRequest(); //请求参数token的值 String token = request.getParameter("token"); if(token==null){ logger.warn("此操作需要先登录系统。。"); currentContext.setSendZuulResponse(false); //拒绝访问 currentContext.setResponseStatusCode(200);//设置相应状态码 try { currentContext.getResponse().getWriter().write("token is empty"); } catch (IOException e) { e.printStackTrace(); } return null; } logger.info("ok"); return null; } }
创建启动类:
@EnableZuulProxy //开启zuul路由网关类
package cn.lijun.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; /** * @author lijun * @date 2019/8/30 11:43 */ @EnableZuulProxy// 开启zuul路由网关功能 @SpringBootApplication public class ZuulServer_7001 { public static void main(String[] args) { SpringApplication.run(ZuulServer_7001.class,args); } }
创建服务监控项目micro-service-10-hystrix-dashboard-9001
创建pom.xml文件
"1.0" encoding="UTF-8"?>"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"> microservice-cloud-01 cn.kgc 1.0-SNAPSHOT ../microservice-cloud-01/pom.xml 4.0.0 cn.kgc micro-service-cloud-10-hystrix-dashboard-9001 1.8 1.8 cn.kgc microservice-cloud-02-api ${project.version} org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-hystrix org.springframework.cloud spring-cloud-starter-netflix-hystrix-dashboard
核心jar包
org.springframework.cloud spring-cloud-starter-netflix-hystrix org.springframework.cloud spring-cloud-starter-netflix-hystrix-dashboard
创建application.yml文件
server: port: 9001
创建启动类
package cn.kgc.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; @EnableHystrixDashboard // 开启服务监控 @SpringBootApplication public class HystrixDashboard_9001 { public static void main(String[] args) { SpringApplication.run(HystrixDashboard_9001.class,args); } }