1.1 声明式服务调用的作用是什么,它解决什么问题
生产者
api
@RequestMapping("/product")
public interface ProductFacade {
@RequestMapping(value="list",method=RequestMethod.GET)
public List<Product> listProduct();
@RequestMapping(value="findAllProduct",method=RequestMethod.GET)
public List<Product> findAllProduct();
@RequestMapping(value="get",method=RequestMethod.GET)
public Product getProduct(@RequestParam("id") Integer id);
//----------------多参数------------------------------
@RequestMapping(value="get1",method=RequestMethod.GET,
consumes=MediaType.APPLICATION\_JSON\_VALUE)
public Product getProduct1(Product obj);
@RequestMapping(value="get2",method=RequestMethod.GET)
public Product getProduct2(@RequestParam("id") Integer id,@RequestParam("name") String name);
//---------------------------post------------------------------
@RequestMapping(value="add",method=RequestMethod.POST,
consumes=MediaType.APPLICATION\_JSON\_VALUE)
public Product addProduct(@RequestBody Product obj);
}
core
@EnableEurekaClient
@SpringBootApplication
@MapperScan("com.agan.book.product.persistence")
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class, args);
}
}
spring.application.name=e-book-product
server.port=8083
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
#默认是hostname 注册,改成IP 注册
eureka.instance.perferIpAddress=true
消费者
spring.application.name=e-book-consumer
server.port=8090
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
#默认是hostname 注册,改成IP 注册
eureka.instance.perferIpAddress=true
package com.agan.book.consumer.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.agan.book.consumer.service.ProductService;
import com.agan.book.product.domain.Product;
/\*\*
\* @author 阿甘
\* @see http://study.163.com/instructor/1016671292.htm
\* @version 1.0
\*/
@RestController
public class ProductController {
@Autowired
private ProductService productService;
@RequestMapping(value="list",method=RequestMethod.GET)
public List<Product> listProduct(){
List<Product> list=this.productService.listProduct();
return list;
}
}
业务层
package com.agan.book.consumer.service;
import org.springframework.cloud.netflix.feign.FeignClient;
import com.agan.book.product.facade.ProductFacade;
/\*\*
\* @author 阿甘
\* @see http://study.163.com/instructor/1016671292.htm
\* @version 1.0
\*/
@FeignClient(name="e-book-product")
public interface ProductService extends ProductFacade{
}
启动类
package com.agan.book.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
/\*\*
\* @author 阿甘
\* @see http://study.163.com/instructor/1016671292.htm
\* @version 1.0
\*/
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
通过使用feign 下面这段代码不用写了
只需这点

1.1 处理复杂参数e-book-consumer-feign-param
控制层
package com.agan.book.consumer.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.agan.book.consumer.service.ProductService;
import com.agan.book.product.domain.Product;
/\*\*
\* @author 阿甘
\* @see http://study.163.com/instructor/1016671292.htm
\* @version 1.0
\*/
@RestController
public class ProductController {
@Autowired
private ProductService productService;
@RequestMapping(value="list",method=RequestMethod.GET)
public List<Product> listProduct(){
List<Product> list=this.productService.listProduct();
return list;
}
@RequestMapping(value="get",method=RequestMethod.GET)
public Product getProduct(@RequestParam("id") Integer id){
return this.productService.getProduct(id);
}
//--------------多参数------------------------------
//不能这么写,因为feign会自动转换为post
@RequestMapping(value="get1",method=RequestMethod.GET)
public Product getProduct1( Product obj){
return this.productService.getProduct1(obj);
}
//get请求只能这样传递对象
@RequestMapping(value="get2",method=RequestMethod.GET)
public Product getProduct2(@RequestParam("id") Integer id,@RequestParam("name") String name){
return this.productService.getProduct2(id,name);
}
//---------------------------post------------------------------
@RequestMapping(value="add",method=RequestMethod.GET)
public Product addProduct(){
Product obj=new Product(2,"漫谈spring cloud分布式服务架构(微服务进阶篇)");
return this.productService.addProduct(obj);
}
}
对接的生产者api接口

1.1.1 业务层ProductService
package com.agan.book.consumer.service;
import org.springframework.cloud.netflix.feign.FeignClient;
import com.agan.book.product.facade.ProductFacade;
/\*\*
\* @author 阿甘
\* @see http://study.163.com/instructor/1016671292.htm
\* @version 1.0
\*/
@FeignClient(name="e-book-product")
public interface ProductService extends ProductFacade{
启动类
ackage com.agan.book.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
/\*\*
\* @author 阿甘
\* @see http://study.163.com/instructor/1016671292.htm
\* @version 1.0
\*/
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
1.1 性能优化:基于Gzip压缩提升通信速度



1.1 性能优化:基于连接池,提升吞吐量

通过连接池,如果传递对象,需要注意添加下面

1.1 springcloud日志记录每个接口URL,状态码和耗时信息
如何把浏览器中信息输出到日志

package com.agan.book.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import feign.Logger;
/\*\*
\* @author 阿甘
\* @see http://study.163.com/instructor/1016671292.htm
\* @version 1.0
\*/
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class ConsumerApplication {
@Bean
public Logger.Level feignLoggerLevel(){
// NONE, 不记录任何信息,默认值。
// BASIC, 记录请求方法、请求URL、状态码和用时。
// HEADERS, 在BASIC的基础上再记录一些常用信息。
// FULL: 记录请求和响应报文的全部内容。
return Logger.Level.FULL;
}
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
效果

feign负载均衡
spring.application.name=e-book-consumer
server.port=8090
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
#默认是hostname 注册,改成IP 注册
eureka.instance.perferIpAddress=true
#全局配置
## 请求连接的超时时间
#ribbon.ConnectTimeout=5000
## 请求处理的超时时间
#ribbon.ReadTimeout=5000
#局部配置
# 对所有操作请求都进行重试
e-book-product.ribbon.OkToRetryOnAllOperations=true
# 对当前实例的重试次数
e-book-product.ribbon.MaxAutoRetries=2
# 切换实例的重试次数
e-book-product.ribbon.MaxAutoRetriesNextServer=0
# 请求连接的超时时间
e-book-product.ribbon.ConnectTimeout=3000
# 请求处理的超时时间
e-book-product.ribbon.ReadTimeout=3000
# 指定具体的服务实例清单
#e-book-product.ribbon.listOfServers=
模拟超时测试
