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包依赖文件。整合项目为一个项目。
<!--maven不支持多继承,使用import来依赖管理配置-->
<scope>import</scope>
pom.xml文件
<?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>cn.kgc</groupId>
<artifactId>microservice-cloud-01</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>../microservice-cloud-02-api</module>
<module>../microservice-cloud-03-provider-product-8001</module>
<module>../microservice-cloud-04-consumer-product-80</module>
<module>../microservice-cloud-05-eureka-6001</module>
<module>../microservice-cloud-05-eureka-6002</module>
<module>../microservice-cloud-04-consumer-product-fegin</module>
<module>../microservice-cloud-03-provider-product-hystrix-8001</module>
<module>../microservice-cloud-9-zuul-getway-7001</module>
</modules>
<!--添加springboot依赖包 采用2.0.7版本-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.7.RELEASE</version>
<relativePath/>
</parent>
<properties>
<!--设置资源编码-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.coppiler.source>1.8</maven.coppiler.source>
<maven.coppiler.target>1.8</maven.coppiler.target>
<!--junit测试包的版本-->
<junit.version>4.12</junit.version>
<!-- spring cloud 采用 Finchley.SR2 版本 -->
<spring-cloud.version>Finchley.SR2</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<!--添加SpringCloud jar包-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<!--maven不支持多继承,使用import来依赖管理配置-->
<scope>import</scope>
</dependency>
<!--导入 mybatis 启动器 mybatis和SpringCloud的整合包-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!--阿里数据源druid数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<!--MySQL数据库驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<!--junit测试类-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
2、创建实体类,工具类子项目 microservice-cloud-02-api
该项目放置实体类及工具类,其服务者和消费者都应该依赖于该项目,以便在实体类中存取数据,和使用工具类
其实体类要实现序列化接口Serializable接口,以便于在不同项目中通过网络调用
pom.xml文件
<?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>microservice-cloud-01</artifactId> <groupId>cn.kgc</groupId> <version>1.0-SNAPSHOT</version> <relativePath>../microservice-cloud-01/pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> <groupId>cn.kgc</groupId> <artifactId>microservice-cloud-02-api</artifactId> <!--jdk版本可以不要--> <properties> <maven.coppiler.source>1.8</maven.coppiler.source> <maven.coppiler.target>1.8</maven.coppiler.target> </properties> </project>
实体类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文件<?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>microservice-cloud-01</artifactId>
<groupId>cn.kgc</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../microservice-cloud-01/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>cn.kgc</groupId>
<artifactId>microservice-cloud-03-provider-product-8001</artifactId>
<properties>
<maven.coppiler.source>1.8</maven.coppiler.source>
<maven.coppiler.target>1.8</maven.coppiler.target>
</properties>
<dependencies>
<!--添加实体类项目的jar包-->
<dependency>
<groupId>cn.kgc</groupId>
<artifactId>microservice-cloud-02-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--springboot web项目核心包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--springBoot test测试包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!--mybatis和springboot整合包-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!--阿里数据源druid数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!--数据库驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--junit测试包-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<!--服务提供者注册进服务中心-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--添加监控依赖用于被监控-->
<dependency>
<groupId>org.springframeeork.boot</groupId>
<artifactId>spring-boot-starter-actuactor</artifactId>
</dependency>
</dependencies> </project>
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
该文件用于设置驼峰命名规则,以便程序与实体类之间的可以映射上
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"></setting>
</settings>
</configuration>
3.1.4创建ProductMapper.xml
路径为:resources.mybatis.mapper.ProductMapper.xml
该文件为mapper接口的映射文件,用于写sql语句
namespace="mapper接口所在的包全路径"
id为mapper接口的方法名。 resultType为mapper接口的返回值类型。 parameterType为参数的数据类型
<?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="cn.kgc.springcloud.mapper.ProductMapper">
<!-- id为mapper接口的方法名。resultType为mapper接口的返回值类型。parameterType为参数的数据类型-->
<select id="findAll" resultType="Product">
SELECT pid,product_name,db_source FROM product;
</select>
<select id="findById" resultType="Product" parameterType="Long">
SELECT pid,product_name,db_source FROM product where pid=#{pid};
</select>
<insert id="addProduct" parameterType="Product">
INSERT INTO product(product_name,db_source) VALUES(#{productName},#{dbSource})
</insert>
</mapper>
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 { //获得所有产品 List<Product> findAll(); //通过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 { //获得所有产品 List<Product> findAll(); //通过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 List<Product> findAll() { 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 List<Product> getfindAll(){ List<Product> 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文件
<?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>microservice-cloud-01</artifactId> <groupId>cn.kgc</groupId> <version>1.0-SNAPSHOT</version> <relativePath>../microservice-cloud-01/pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> <groupId>cn.kgc</groupId> <artifactId>microservice-cloud-03-provider-product-hystrix-8001</artifactId> <properties> <maven.coppiler.source>1.8</maven.coppiler.source> <maven.coppiler.target>1.8</maven.coppiler.target> </properties> <dependencies> <!--添加实体类项目的jar包--> <dependency> <groupId>cn.kgc</groupId> <artifactId>microservice-cloud-02-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--springboot web项目核心包--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--springBoot test测试包--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <!--mybatis和springboot整合包--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <!--阿里数据源druid数据源--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> </dependency> <!--数据库驱动包--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--junit测试包--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <!--服务提供者注册进服务中心--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!--添加hystirx依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
<!--添加监控依赖,用于被监控-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency> </dependencies>
</project>
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
该文件用于设置驼峰命名规则,以便程序与实体类之间的可以映射上
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"></setting>
</settings>
</configuration>
3.1.4创建ProductMapper.xml
路径为:resources.mybatis.mapper.ProductMapper.xml
该文件为mapper接口的映射文件,用于写sql语句
namespace="mapper接口所在的包全路径"
id为mapper接口的方法名。 resultType为mapper接口的返回值类型。 parameterType为参数的数据类型
<?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="cn.kgc.springcloud.mapper.ProductMapper">
<select id="findAll" resultType="Product">
SELECT pid,product_name,db_source FROM product;
</select>
<select id="findById" resultType="Product" parameterType="Long">
SELECT pid,product_name,db_source FROM product where pid=#{pid};
</select>
<insert id="addProduct" parameterType="Product">
INSERT INTO product(product_name,db_source) VALUES(#{productName},#{dbSource})
</insert>
</mapper>
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 { //获得所有产品 List<Product> findAll(); //通过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<Product> 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 List<Product> findAll() { 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 List<Product> getfindAll(){ List<Product> 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文件
<?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>microservice-cloud-01</artifactId> <groupId>cn.kgc</groupId> <version>1.0-SNAPSHOT</version> <relativePath>../microservice-cloud-01/pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> <groupId>cn.kgc</groupId> <artifactId>microservice-cloud-04-consumer-product-80</artifactId> <properties> <maven.coppiler.source>1.8</maven.coppiler.source> <maven.coppiler.target>1.8</maven.coppiler.target> </properties> <dependencies> <dependency> <groupId>cn.kgc</groupId> <artifactId>microservice-cloud-02-api</artifactId> <version>1.0-SNAPSHOT</version> <scope>compile</scope> </dependency> <!--springboot web启动器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--spring-cloud-starter-netflix-eureka-clien 会自动添加spring-cloud-starter-netflix-ribbon--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies> </project>
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 List<Product> list() { 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文件
<?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>microservice-cloud-01</artifactId> <groupId>cn.kgc</groupId> <version>1.0-SNAPSHOT</version> <relativePath>../microservice-cloud-01/pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> <groupId>cn.kgc</groupId> <artifactId>microservice-cloud-04-consumer-product-fegin</artifactId> <properties> <maven.coppiler.source>1.8</maven.coppiler.source> <maven.coppiler.target>1.8</maven.coppiler.target> </properties> <dependencies> <dependency> <groupId>cn.kgc</groupId> <artifactId>microservice-cloud-02-api</artifactId> <version>1.0-SNAPSHOT</version> <scope>compile</scope> </dependency> <!--springboot web启动器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--Ribbon 相关的依赖--> <!--spring-cloud-starter-netflix-eureka-clien 会自动添加spring-cloud-starter-netflix-ribbon--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!--fegin的依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies> </project>
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) List<Product> list(); @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 List<Product> list() { 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 List<Product> list() { 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文件
<?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>microservice-cloud-01</artifactId> <groupId>cn.kgc</groupId> <version>1.0-SNAPSHOT</version> <relativePath>../microservice-cloud-01/pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> <groupId>cn.kgc</groupId> <artifactId>microservice-cloud-05-eureka-6001</artifactId> <!--导入Eureka Server服务端依赖--> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies> </project>
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文件
<?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>microservice-cloud-01</artifactId> <groupId>cn.kgc</groupId> <version>1.0-SNAPSHOT</version> <relativePath>../microservice-cloud-01/pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> <groupId>cn.kgc</groupId> <artifactId>microservice-cloud-05-eureka-6002</artifactId> <!--导入Eureka Server服务端依赖,说明这是服务注册中心--> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies> </project>
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文件
<?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>microservice-cloud-01</artifactId> <groupId>cn.kgc</groupId> <version>1.0-SNAPSHOT</version> <relativePath>../microservice-cloud-01/pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> <groupId>cn.kgc</groupId> <artifactId>microservice-cloud-9-zuul-getway-7001</artifactId> <properties> <maven.coppiler.source>1.8</maven.coppiler.source> <maven.coppiler.target>1.8</maven.coppiler.target> </properties> <dependencies> <!--服务提供者注册进服务中心--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!--springboot 核心包--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--路由网关 jar包--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> </dependencies> </project>
添加核心jar包
<!--路由网关 jar包-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
创建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文件
<?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>microservice-cloud-01</artifactId> <groupId>cn.kgc</groupId> <version>1.0-SNAPSHOT</version> <relativePath>../microservice-cloud-01/pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> <groupId>cn.kgc</groupId> <artifactId>micro-service-cloud-10-hystrix-dashboard-9001</artifactId> <properties> <maven.coppiler.source>1.8</maven.coppiler.source> <maven.coppiler.target>1.8</maven.coppiler.target> </properties> <dependencies> <!--添加实体类依赖--> <dependency> <groupId>cn.kgc</groupId> <artifactId>microservice-cloud-02-api</artifactId> <version>${project.version}</version> </dependency> <!--springboot核心包--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--熔断器hystrix依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <!--添加hystrix-dashboard服务监控依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> </dependency> </dependencies> </project>
核心jar包
<!--熔断器hystrix依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--添加hystrix-dashboard服务监控依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
创建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); } }

浙公网安备 33010602011771号