基于搭建好的Eureka Server+Eureka Client:https://www.cnblogs.com/xuyiqing/p/10861541.html

有了服务,那么现在学习如何调用服务

上文搭建的是商品服务,以下搭建订单服务,订单服务调用商品服务

对Eureka Client进行改造,方便以后得到数据来源

在商品服务的Controller层注入端口号,并进行回显:

package org.dreamtech.product.controller;

import org.dreamtech.product.domain.Product;
import org.dreamtech.product.service.ProductService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; @RestController
@RequestMapping("/api/product")
public class ProductController { @Value("${server.port}")
private String port; private final ProductService productService; @Autowired
public ProductController(ProductService productService) {
this.productService = productService;
} @RequestMapping("/list")
public Object list() {
return productService.getProductList();
} @RequestMapping("/find")
public Object findById(@RequestParam("id") int id) {
Product product = productService.findById(id);
Product result = new Product();
BeanUtils.copyProperties(product,result);
result.setName(result.getName()+" data from port="+port);
return result;
} }

启动Eureka Server,8761端口

启动三个商品服务,一个项目8771端口,一个8772端口,一个8773端口:

多实例启动方法如下图

新建一个SpringBoot项目order-service:

Web模块必须的,由于订单服务本身也是服务需要Eureka,最后负载均衡调用Ribbon

订单服务开发(模拟实现):

实体类

package org.dreamtech.orderservice.domain;

import java.io.Serializable;
import java.util.Date; public class ProductOrder implements Serializable {
//ID
private int id;
//商品名称
private String productName;
//订单号
private String tradeNo;
//价格
private int price;
//创建时间
private Date createTime;
//用户ID
private int userId;
//用户名
private String userName; public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} public int getUserId() {
return userId;
} public void setUserId(int userId) {
this.userId = userId;
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getProductName() {
return productName;
} public void setProductName(String productName) {
this.productName = productName;
} public String getTradeNo() {
return tradeNo;
} public void setTradeNo(String tradeNo) {
this.tradeNo = tradeNo;
} public int getPrice() {
return price;
} public void setPrice(int price) {
this.price = price;
} public Date getCreateTime() {
return createTime;
} public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
}

为了方便,和商品服务一样,不调用数据库,只做简单的模拟:

在SpringBoot启动类中加入Bean

package org.dreamtech.orderservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate; @SpringBootApplication
public class OrderServiceApplication { public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
} @Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}

配置文件对端口和服务名称进行配置:

server:
port: 8781
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
spring:
application:
name: order-service

Controller:

package org.dreamtech.orderservice.controller;

import org.dreamtech.orderservice.service.ProductOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; @RestController
@RequestMapping("/api/order")
public class OrderController {
private final ProductOrderService productOrderService; @Autowired
public OrderController(ProductOrderService productOrderService) {
this.productOrderService = productOrderService;
} @RequestMapping("/save")
public Object save(@RequestParam("user_id") int userId, @RequestParam("product_id") int productId) {
return productOrderService.save(userId, productId);
}
}

Service:

package org.dreamtech.orderservice.service;

import org.dreamtech.orderservice.domain.ProductOrder;

public interface ProductOrderService {
/**
* 下单接口
*
* @param userId 用户ID
* @param productId 商品ID
* @return ProductOrder
*/
ProductOrder save(int userId, int productId);
}
package org.dreamtech.orderservice.service.impl;

import org.dreamtech.orderservice.domain.ProductOrder;
import org.dreamtech.orderservice.service.ProductOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate; import java.util.Date;
import java.util.Map;
import java.util.UUID; @Service
public class ProductOrderServiceImpl implements ProductOrderService { private final RestTemplate restTemplate; @Autowired
public ProductOrderServiceImpl(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
} @Override
@SuppressWarnings("unchecked")
public ProductOrder save(int userId, int productId) { Map<String, Object> productMap = restTemplate.getForObject("http://product-service/api/product/find?id=" + productId, Map.class); ProductOrder productOrder = new ProductOrder();
productOrder.setCreateTime(new Date());
productOrder.setUserId(userId);
productOrder.setTradeNo(UUID.randomUUID().toString()); if (productMap != null) {
productOrder.setProductName(productMap.get("name").toString());
productOrder.setPrice(Integer.parseInt(productMap.get("price").toString()));
}
return productOrder;
}
}

注意:getForObject方法的url中product-service是我在商品服务中配置的名称

启动项目,如果正常情况,Eureka应该显示如图:

访问http://localhost:8781/api/order/save?user_id=1&product_id=2多次,我将多次的返回结果记录在下:

{"id":0,"productName":"iPhone2 data from port=8771","tradeNo":"8beb0fe0-83ef-4d23-ae53-9399bac7eacc","price":2222,"createTime":"2019-05-15T03:21:12.432+0000","userId":1,"userName":null}
{"id":0,"productName":"iPhone2 data from port=8773","tradeNo":"09544f1d-462b-413a-b14a-cc9d599bce39","price":2222,"createTime":"2019-05-15T03:21:48.467+0000","userId":1,"userName":null}
{"id":0,"productName":"iPhone2 data from port=8771","tradeNo":"543e83a7-3e58-48bb-8aba-bd7635a10131","price":2222,"createTime":"2019-05-15T03:21:57.244+0000","userId":1,"userName":null}
{"id":0,"productName":"iPhone2 data from port=8772","tradeNo":"b30bbd40-49e8-4001-917a-0ae36b172463","price":2222,"createTime":"2019-05-15T03:22:06.509+0000","userId":1,"userName":null}

可以观察到,我开启了三个商品服务,这里自动在三个服务中进行了负载均衡,8771-8773随机访问

在SpringBoot启动类中加入Bean是一种方式,还有另一种调用方式:

不过还是推荐第一种

package org.dreamtech.orderservice.service.impl;

import org.dreamtech.orderservice.domain.ProductOrder;
import org.dreamtech.orderservice.service.ProductOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate; import java.util.Date;
import java.util.Map;
import java.util.UUID; @Service
public class ProductOrderServiceImpl implements ProductOrderService {
private final LoadBalancerClient loadBalancer; @Autowired
public ProductOrderServiceImpl(, LoadBalancerClient loadBalancer) {
this.loadBalancer = loadBalancer;
} @Override
@SuppressWarnings("unchecked")
public ProductOrder save(int userId, int productId) { ServiceInstance instance = loadBalancer.choose("product-service");
String url = String.format("http://%s:%s/api/product/find?id="+productId,instance.getHost(),instance.getPort());
RestTemplate restTemplate = new RestTemplate();
Map<String, Object> productMap = restTemplate.getForObject(url, Map.class); ProductOrder productOrder = new ProductOrder();
productOrder.setCreateTime(new Date());
productOrder.setUserId(userId);
productOrder.setTradeNo(UUID.randomUUID().toString()); if (productMap != null) {
productOrder.setProductName(productMap.get("name").toString());
productOrder.setPrice(Integer.parseInt(productMap.get("price").toString()));
}
return productOrder;
}
}

自定义负载均衡策略:

Ribbon默认是轮询策略

比如我想要使用随机策略,配置如下:

product-service:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

注意:服务名的一致,比如区分"_"和"-"

通常情况下,不需要改变策略,轮询策略为最佳

但是如果有一个好机器,一堆差机器,那么可以调整好机器的权重

Spring Cloud(3):Ribbon的使用的更多相关文章

  1. spring cloud 使用ribbon简单处理客户端负载均衡

    假如我们的multiple服务的访问量剧增,用一个服务已经无法承载, 我们可以把Hello World服务做成一个集群. 很简单,我们只需要复制Hello world服务,同时将原来的端口8762修改 ...

  2. spring cloud: 关闭ribbon负载均衡

    spring cloud: 关闭ribbon负载均衡 1.eureka服务 2.2个user服务:7900/7901 3,movie服务 movie服务去请求 user的用户信息,而此时只想请求790 ...

  3. Spring Cloud 之 Ribbon

    新建Spring Boot工程,命名为ribbon 1.pom.xml添加依赖 <?xml version="1.0" encoding="UTF-8"? ...

  4. 笔记:Spring Cloud Feign Ribbon 配置

    由于 Spring Cloud Feign 的客户端负载均衡是通过 Spring Cloud Ribbon 实现的,所以我们可以直接通过配置 Ribbon 的客户端的方式来自定义各个服务客户端调用的参 ...

  5. Spring cloud 之Ribbon(一)基本使用

    简介 Spring cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它是基于Netflix的Riboon实现的.Ribbon是客户端负载均衡器,这有别语例如Nginx服务端负载 ...

  6. Spring Cloud Gateway Ribbon 自定义负载均衡

    在微服务开发中,使用Spring Cloud Gateway做为服务的网关,网关后面启动N个业务服务.但是有这样一个需求,同一个用户的操作,有时候需要保证顺序性,如果使用默认负载均衡策略,同一个用户的 ...

  7. 从零开始学spring cloud(六) -------- Ribbon

    一.Ribbon介绍 Ribbon就是客户端侧负责均衡实现的一种方式,那么Ribbon是什么呢? Ribbon是Netflix发布的云中间层服务开源项目,其主要功能是提供客户端侧负载均衡算法.Ribb ...

  8. spring cloud 自定义ribbon客户端

    一.自定义Ribbon客户端-[方式一]配置类 1.1.自定义负载规则 增加RibbonConfiguration.java配置类 public class RibbonConfiguration { ...

  9. Spring Cloud Feign Ribbon 配置

    由于 Spring Cloud Feign 的客户端负载均衡是通过 Spring Cloud Ribbon 实现的,所以我们可以直接通过配置 Ribbon 的客户端的方式来自定义各个服务客户端调用的参 ...

  10. Spring Cloud之Ribbon与Nginx区别

    客户端负载均衡器 在SpringCloud中Ribbon负载均衡客户端,会从eureka注册中心服务器端上获取服务注册信息列表,缓存到本地. 让后在本地实现轮训负载均衡策略. Ribbon与Nginx ...

随机推荐

  1. PCLVisualizer可视化类(2)

    博客转载自:http://www.pclcn.org/study/shownews.php?lang=cn&id=163 可视化点云颜色特征 所示,点赋予不同的颜色表征其对应的z轴值不同.PC ...

  2. 6.5 系统打开缓慢,怎么办?---更新Ubuntu系统

    早早的来公司打开电脑,希望看到Ubuntu能启动成功.可是,当我重启后,使用Ubuntu系统,打开界面速度非常慢,当时,又怀疑自己安装出错了.而且,6.2日Ubuntu系统的工作日志又没了.无奈,我把 ...

  3. 【mysql存储引擎】

    看你的mysql现在已提供什么存储引擎: mysql> show engines;   看你的mysql当前默认的存储引擎: mysql> show variables like '%st ...

  4. poj2763(lca / RMQ + 线段树)

    题目链接: http://poj.org/problem?id=2763 题意: 第一行输入 n, q, s 分别为树的顶点个数, 询问/修改个数, 初始位置. 接下来 n - 1 行形如 x, y, ...

  5. 置换群(本蒟蒻瞎BB的)(未完)

    置换群(本蒟蒻瞎BB的)(未完) 群的定义 给定一个集合\(G=\{a, b, c...\}\)和集合\(G\)上的二元运算*,并满足: 封闭性:\(\forall a, b \in G, \exis ...

  6. 在Linux系统下远程连接oracle的防火墙设置

    在Linux系统要远程连接Oracle的防火墙设置方法: 打开5801至5810 端口用于vnc iptables -I INPUT -p tcp --dport 5801:5810 -j ACCEP ...

  7. 问题 Can't load AMD 64-bit .dll on a IA 32-bit platform

    问题简要描述: java.lang.UnsatisfiedLinkError: F:\Tools\tomcat6045\tomcat6.0.45_x64\apache-tomcat-6.0.45\bi ...

  8. 日志记录:MySQL系列之十一

    一.SQL命令历史 ~/.mysql_history 记录了在mysql中执行的命令历史 二.事务日志 transaction log:事务型存储引擎自行管理和使用 在一个事务提交后还没有存到磁盘的情 ...

  9. java怎样防止内存溢出

    引起内存溢出的原因有很多种,小编列举一下常见的有以下几种: 1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据:2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收:3.代码中存在死 ...

  10. Webpack+Vue构建项目

    第一步:单纯的搭建出来我们的项目,并且通过webpack打包一个bundle.js然后运行起来 步骤: 1.建立项目必要的文件和文件夹(见截图) 2.配置webpack.develop.config. ...