DROp TABLE IF EXISTS `product`;
CREATE TABLE `product` (
`productId` bigint(20) NOT NULL AUTO_INCREMENT,
`productName` varchar(50) DEFAULT NULL,
`productDesc` varchar(50) DEFAULT NULL,
PRIMARY KEY (`productId`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of product
-- ----------------------------
INSERT INTO `product` VALUES ('1', '电子锁骨', 'cloud');
INSERT INTO `product` VALUES ('2', 'Springboot', 'cloud');
INSERT INTO `product` VALUES ('3', '水表', 'cloud');
INSERT INTO `product` VALUES ('4', '门禁', 'cloud');
INSERT INTO `product` VALUES ('5', '摄像头', 'cloud');
INSERT INTO `product` VALUES ('8', 'SpringCloud', 'cloud');
INSERT INTO `product` VALUES ('9', 'RestTemplate', 'cloud');
父工程
公共模块,存放实体类,工具类等等4.0.0 com.xysd.cloud cloudexecise2 pom 1.0-SNAPSHOT cloudapi cloudproviderproduct cloudconsumer clouderureka org.springframework.boot spring-boot-starter-parent 2.1.6.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-logging org.projectlombok lombok 1.18.4 provided org.springframework.cloud spring-cloud-dependencies Greenwich.RELEASE pom import cloudexecise2 org.apache.maven.plugins maven-compiler-plugin ${java.version} ${java.version}
package com.xysd.cloud.entity;
import java.io.Serializable;
public class Product implements Serializable {
private Long productId;
private String productName;
private String productDesc;
public String getProductDesc() {
return productDesc;
}
public void setProductDesc(String productDesc) {
this.productDesc = productDesc;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Long getProductId() {
return productId;
}
public void setProductId(Long productId) {
this.productId = productId;
}
@Override
public String toString() {
return "Product{" +
"productId=" + productId +
", productName='" + productName + ''' +
", productDesc='" + productDesc + ''' +
'}';
}
}
注册中心cloudeureka
依赖
配置application.ymlcloudexecise2 com.xysd.cloud 1.0-SNAPSHOT 4.0.0 cloud-erureka UTF-8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-devtools org.springframework.cloud spring-cloud-starter-netflix-eureka-server eureka-server org.springframework.boot spring-boot-maven-plugin com.xysd.cloud.EurekaApp repackage
server:
port: 8761
eureka:
instance:
hostname: localhost # 定义 Eureka 实例所在的主机名称
client:
fetch-registry: false #是否从eureka中获取注册信息
register-with-eureka: false #是否将自己注册到注册中心
service-url:
defaultZone: http://localhost:8761/eureka/
代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaApp {
public static void main(String[] args) {
SpringApplication.run(EurekaApp.class,args);
}
}
生产主cloudproviderproduct
依赖
配置application.ymlcloudexecise2 com.xysd.cloud 1.0-SNAPSHOT 4.0.0 cloud-provider-product org.springframework.cloud spring-cloud-starter-netflix-eureka-client com.xysd.cloud cloud-api 1.0.0 mysql mysql-connector-java com.alibaba druid 1.0.31 org.mybatis.spring.boot mybatis-spring-boot-starter 1.3.0 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-devtools org.springframework.boot spring-boot-starter-actuator cloud-eureka src/main/resources true org.apache.maven.plugins maven-resources-plugin $ org.apache.maven.plugins maven-compiler-plugin ${java.version} ${java.version}
server:
port: 8080
mybatis: #mybatyis的配置
mapper-locations: classpath:mapper/*.xml
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 配置当前要使用的数据源的操作类型
driver-class-name: com.mysql.cj.jdbc.Driver # 配置MySQL的驱动程序类
url: jdbc:mysql://localhost:3306/cloud?serverTimezone=GMT%2B8 # 数据库连接地址
username: root # 数据库用户名
password: root # 数据库连接密码
application:
name: cloudproviderproduct
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
instance-id: cloudproviderproduct
prefer-ip-address: true #显示ip
info:
app.name: cloudproviderproduct
company.name: xysd
build.artifactId: $project.artifactId$
build.modelVersion: $project.modelVersion$
代码
package com.xysd.cloud.mapper;
import com.xysd.cloud.entity.Product;
import java.util.List;
public interface ProductMapper {
boolean create(Product product);
public Product findById(Long id);
public List findAll();
}
package com.xysd.cloud.service;
import com.xysd.cloud.entity.Product;
import java.util.List;
public interface ProductService {
Product get(long id);
boolean add(Product product);
List list();
}
package com.xysd.cloud.service.impl;
import com.xysd.cloud.entity.Product;
import com.xysd.cloud.mapper.ProductMapper;
import com.xysd.cloud.service.ProductService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class ProductServiceImpl implements ProductService {
@Resource
private ProductMapper productMapper;
@Override
public Product get(long id) {
return productMapper.findById(id);
}
@Override
public boolean add(Product product) {
System.out.println(product);
return productMapper.create(product);
}
@Override
public List list() {
return productMapper.findAll();
}
}
package com.xysd.cloud.controller;
import com.xysd.cloud.entity.Product;
import com.xysd.cloud.service.ProductService;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@RestController
@RequestMapping("/product")
public class ProductController {
@Resource
private ProductService productService;
@RequestMapping(value = "/get/{id}",method = RequestMethod.GET)
public Object get(@PathVariable("id") long id) {
return this.productService.get(id);
}
@RequestMapping(value = "/add")
public Object add(@RequestBody Product product) {
return this.productService.add(product);
}
@RequestMapping(value = "/list")
public Object list() {
return this.productService.list();
}
}
消费者cloudconsumer
依赖
配置application.ymlcloudexecise2 com.xysd.cloud 1.0-SNAPSHOT 4.0.0 cloud-consumer com.xysd.cloud cloud-api 1.0.0 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-devtools org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.cloud spring-cloud-starter-openfeign org.springframework.boot spring-boot-starter-actuator cloud-eureka src/main/resources true org.apache.maven.plugins maven-resources-plugin $ org.apache.maven.plugins maven-compiler-plugin ${java.version} ${java.version}
server:
port: 8083
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
instance-id: cloudconsumerproduct
prefer-ip-address: true #显示ip
spring:
application:
name: cloudconsumerproduct
info:
app.name: cloudproviderproduct
company.name: xysd
build.artifactId: $project.artifactId$
build.modelVersion: $project.modelVersion$
代码
package com.xysd.cloud.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 RestConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
package com.xysd.cloud.controller;
import com.xysd.cloud.entity.Product;
import com.xysd.cloud.service.ProductFeignClient;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/consumer")
public class ConsumerProductController {
public static final String PRODUCT_GET_URL = "http://cloudproviderproduct/product/get/";
public static final String PRODUCT_LIST_URL="http://cloudproviderproduct/product/list/";
public static final String PRODUCT_ADD_URL = "http://cloudproviderproduct/product/add/";
@Resource //必须使用应用名(服务名大小写都可以)作为代替ip:端口,
private RestTemplate restTemplate;
@RequestMapping("/product/get")
public Object getProduct(@RequestParam(value = "id") long id) {
String url = PRODUCT_GET_URL + id;
System.out.println(url);
Product product = restTemplate.getForObject(url, Product.class);
return product;
}
@RequestMapping("/product/list")
public Object listProduct() {
List list = restTemplate.getForObject(PRODUCT_LIST_URL, List.class);
return list;
}
@RequestMapping("/product/add")
public Object addPorduct(@RequestBody Product product) {
System.out.println(product);
Boolean result = restTemplate.postForObject(PRODUCT_ADD_URL, product, Boolean.class);
return result;
}
}
测试
先启动cloudeureka,在启动cloudproviderproduct,如何启动cloudconsumer,访问http://localhost:8083/consumer/product/get?id=1
服务降级在消费者端操作
依赖
org.springframework.cloud
spring-cloud-starter-netflix-hystrix
配置
hystrix:
command:
default:
execution:
isolation:
strategy: ExecutionIsolationStrategy.SEMAPHORE #信号量隔离
thread:
timeoutInMilliseconds: 1000 #默认的连接超时时间1秒,若1秒没有返回数据,自动的触发降级逻辑
代码
基于方法降级
package com.xysd.cloud.controller;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.xysd.cloud.entity.Product;
import com.xysd.cloud.service.ProductFeignClient;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/consumer")
public class ConsumerProductController {
public static final String PRODUCT_GET_URL = "http://cloudproviderproduct/product/get/";
public static final String PRODUCT_LIST_URL="http://cloudproviderproduct/product/list/";
public static final String PRODUCT_ADD_URL = "http://cloudproviderproduct/product/add/";
@Resource //必须使用应用名作为代替ip:端口,
private RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "getProductFallBack")
@RequestMapping("/product/get")
public Object getProduct(@RequestParam(value = "id") long id) {
String url = PRODUCT_GET_URL + id;
System.out.println(url);
Product product = restTemplate.getForObject(url, Product.class);
return product;
}
public Object getProductFallBack(@RequestParam(value = "id") long id){
Product product = new Product();
product.setProductDesc("测试hystrix降级方法");
product.setProductName("hystrix");
return product;
}
@RequestMapping("/product/list")
public Object listProduct() {
List list = restTemplate.getForObject(PRODUCT_LIST_URL, List.class);
return list;
}
@RequestMapping("/product/add")
public Object addPorduct(@RequestBody Product product) {
System.out.println(product);
Boolean result = restTemplate.postForObject(PRODUCT_ADD_URL, product, Boolean.class);
return result;
}
}
基于类服务降级
package com.xysd.cloud.controller;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.xysd.cloud.entity.Product;
import com.xysd.cloud.service.ProductFeignClient;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.List;
@DefaultProperties(defaultFallback = "getProductFallBack")
@RestController
@RequestMapping("/consumer")
public class ConsumerProductController {
public static final String PRODUCT_GET_URL = "http://cloudproviderproduct/product/get/";
public static final String PRODUCT_LIST_URL="http://cloudproviderproduct/product/list/";
public static final String PRODUCT_ADD_URL = "http://cloudproviderproduct/product/add/";
@Resource //必须使用应用名作为代替ip:端口,
private RestTemplate restTemplate;
@RequestMapping("/product/get")
public Object getProduct(@RequestParam(value = "id") long id) {
String url = PRODUCT_GET_URL + id;
System.out.println(url);
Product product = restTemplate.getForObject(url, Product.class);
return product;
}
public Object getProductFallBack(@RequestParam(value = "id") long id){
Product product = new Product();
product.setProductDesc("测试hystrix降级方法");
product.setProductName("hystrix");
return product;
}
@RequestMapping("/product/list")
public Object listProduct() {
List list = restTemplate.getForObject(PRODUCT_LIST_URL, List.class);
return list;
}
@RequestMapping("/product/add")
public Object addPorduct(@RequestBody Product product) {
System.out.println(product);
Boolean result = restTemplate.postForObject(PRODUCT_ADD_URL, product, Boolean.class);
return result;
}
}



