SpringCloud 微服务消费者之间相互调用的方式
在微服务架构中,业务都会被拆分成一个独立的服务。Spring cloud有两种服务调用方式,一种是ribbon+restTemplate,另一种是feign
搭建服务注册中心可以参考:https://www.cnblogs.com/wanghy898/p/11167301.html 启动服务注册中心
启动配置中心服务可以参考:https://www.cnblogs.com/wanghy898/p/11167465.html 启动分布式配置中心
自己在git服务器上新建自己的配置文件:
新建两个springboot项目sell-product和sell-order两个服务并分别在2个服务的pom.xml文件中引入核心依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<!-- alibaba的druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.14</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
在sell-produc服务中的bootstrap.yml文件中添加配置信息:
server:
port: 8083
#以下是从统一配置中心获取
spring:
application:
name: product
# 由于配置了公共配置 所以直接从公共配置中心拉取即可
cloud:
config:
discovery:
enabled: true
service-id: SELL-CONFIG #代表引用公共配置服务
profile: dev #此处生产环境也可以不用填写
在sell-order服务中的bootstrap.yml文件中添加配置信息:
server:
port: 8084
#以下是从统一配置中心获取
spring:
application:
name: order
# 由于配置了公共配置 所以直接从公共配置中心拉取即可
cloud:
config:
discovery:
enabled: true
service-id: SELL-CONFIG #代表引用公共配置服务
profile: dev #此处生产环境也可以不用填写
运行sql脚本(mysql)创建 product表和order表,数据随便插入几条测试
--------------------product表------------------------------
CREATE TABLE `product_info` (
`product_id` varchar(32) NOT NULL,
`product_name` varchar(64) NOT NULL COMMENT '商品名称',
`product_price` decimal(8,2) NOT NULL COMMENT '单价',
`product_stock` int(11) NOT NULL COMMENT '库存',
`product_description` varchar(64) DEFAULT NULL COMMENT '描述',
`product_icon` varchar(512) DEFAULT NULL COMMENT '小图',
`product_status` tinyint(3) DEFAULT '0' COMMENT '商品状态,0正常1下架',
`category_type` int(11) NOT NULL COMMENT '类目编号',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--------------------order表------------------------------
CREATE TABLE `order_master` (
`order_id` varchar(32) NOT NULL,
`buyer_name` varchar(32) NOT NULL COMMENT '买家名字',
`buyer_phone` varchar(32) NOT NULL COMMENT '买家电话',
`buyer_address` varchar(128) NOT NULL COMMENT '买家地址',
`buyer_openid` varchar(64) NOT NULL COMMENT '买家微信openid',
`order_amount` decimal(8,2) NOT NULL COMMENT '订单总金额',
`order_status` tinyint(3) NOT NULL DEFAULT '0' COMMENT '订单状态, 默认为新下单',
`pay_status` tinyint(3) NOT NULL DEFAULT '0' COMMENT '支付状态, 默认未支付',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`order_id`),
KEY `idx_buyer_openid` (`buyer_openid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
sell-product服务中实体类Product:
@Data @TableName("product_info") public class Product { private String productId; private String productName; private BigDecimal productPrice; private int productStock; private String productDescription; private String productIcon; private int productStatus; private int categoryType; private Date createTime; private Date updateTime; }
sell-order服务中实体类Order:
import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @TableName("order_master") @Data public class Order { private String orderId; private String buyerName; private String buyerPhone; private String buyerAddress; private String buyerOpenid; private String orderAmount; private String orderStatus; private String payStatus; private String createTime; private String updateTime; }
sell-order服务中mapper:
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import wanghy.com.cn.entity.Order;
public interface OrderMapper extends BaseMapper<Order> {
}
sell-product服务中mapper:
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import wanghy.com.cn.entity.Product;
public interface ProductMapper extends BaseMapper<Product> {
}
sell-product服务 service层实现
public class ProductServiceImpl implements IProductService { @Autowired private ProductMapper productMapper; @Override public ServerResponse<Object> getProducts() { QueryWrapper<Product> queryWrapper = new QueryWrapper<>(); List<Product> products = productMapper.selectList(queryWrapper); return ServerResponse.sucess("获取产品列表成功", products); } }
sell-order服务 service层实现
@Service public class OrderServiceImpl implements IOrderService { @Autowired private OrderMapper orderMapper; @Override public ServerResponse<Object> getOrders() { QueryWrapper<Order> wrapper = new QueryWrapper<>(); List<Order> orders = orderMapper.selectList(wrapper); return ServerResponse.sucess("获取数据成功",orders); } }
在sell-order服务的controller中想调用sell-product服务中的服务:
方式一:在sell-order服务中通过rest的方式调用sell-product服务:
@RestController
@RequestMapping("/order")
@Slf4j
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/orderList")
public ServerResponse<Object> getOrders() {
Object object = restTemplate.getForObject("http://PRODUCT/product/productList",String.class);
log.info("数据为:{}",object);
return object;
}
}
方式二:在sell-order服务中通过feign的方式调用sell-product服务:
创建一个包feignClients,再创建一个interface ProductClient
@FeignClient(name = "PRODUCT")
public interface ProductClient {
@RequestMapping("/product/productList")
public Object getProducts();
}
然后在controller中调用即可
@RestController
@RequestMapping("/order")
@Slf4j
public class OrderController {
@Autowired
private ProductClient productClient;
@RequestMapping("/products")
public Object getProductInfoList() {
Object object = productClient.getProducts();
return ServerResponse.sucess("成功", object);
}
}
在启动类中加入
在两个服务的启动类中都加入以下依赖:
@SpringCloudApplication //替代@SpringBootApplication @EnableDiscoveryClient
@MapperScan("wanghy.com.cn.mapper") //扫描mappper
@EnableFeignClients(basePackages = "wanghy.com.cn.feinClients") //加上此注解用于feign client的调用
public class SellProductApplication { public static void main(String[] args) { SpringApplication.run(SellProductApplication.class, args); }
@Bean
@LoadBalanced //基于rest+ribbon的调用方式需要加此注解
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
启动进行测试。