ribbon是springcloud提供的一个客户端负载均衡
本人没有实际的使用场景 ,只是结合目前公司的逻辑简单进行了些封装和探索。希望大神多指点,首先是POM 我们先构建ribbon
<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>org.axl</groupId>
<artifactId>eureka1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.7.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.7</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.38</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Dalston.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
我这里比别的教程多引入一个fastjson
因为我这里做了post的封装
网上基本上都是简单的get封装
第二部 在spring boot的启动类中加入如下代码
package com.axl.blog;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
/**
* 启动类
* 此类需要为注解配置类的上一层包才可以对注解进行bean注入操作
* @author AXL
*
*/
@EnableDiscoveryClient
@SpringBootApplication
public class RibbonApplication {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
}
}
第三步、写一个controller,并写入如下代码,我这个方法封装了POST和GET的请求,而且一个方法支持多个服务(虽然不知道这么做对不对,主要是没实际在项目上实践过)
@Resource
private RestTemplate restTemplate;
@RequestMapping(value="/{serverName}/{path1}")
public String serverOne(HttpServletRequest request,
@PathVariable String serverName,
@PathVariable String path1,
@RequestBody(required=false) JSONObject postData
){
System.out.println("一阶调用");
String queryString=request.getQueryString();
StringBuffer url=new StringBuffer();
url.append("http://").append(serverName).append("/").append(path1);
if(queryString!=null){
url.append("?").append(queryString).toString();
}
System.out.println(queryString);
System.out.println(url);
String requestMethod=request.getMethod();
if(postData !=null){
System.out.println("postData="+postData.toString());
}
if(requestMethod.equals("POST")){
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
HttpEntity<String> formEntity = null;
if(postData!=null){
formEntity = new HttpEntity<String>(postData.toString(), headers);
}else{
formEntity = new HttpEntity<String>(null, headers);
}
return restTemplate.postForEntity(url.toString(), formEntity, String.class).getBody();
}else{
return restTemplate.getForEntity(url.toString(), String.class).getBody();
}
}
这个方法处理了一阶的请求,的GET和POST带参数或者不带参数,后面对多阶的的支持只需要拓展
url.append(“http://”).append(serverName).append(“/”).append(path1);
在接收更多的参数即可,
通过访问这个接口会自动负载均衡到 对应的微服务的服务器上
GLOUP-SERVICE UP (2) -
DESKTOP-23R12DT:gloup-service:8001 ,
DESKTOP-23R12DT:gloup-service:8002
这个是我eureka中两个相同的微服务,通过浏览器访问
http://127.0.0.1:7002/GLOUP-SERVICE/hello
会自动在两个服务器间轮询切换
当然ribbon还有其他的 负载的策略,这里不做说明了~网上搜一下很多
最后我们可以需要测试POST 这个就有点难办了 我这里做了个demo有兴趣可以试一下
因为我们要用浏览器测试首先要解决一下跨域问题
JSONP 听着不错可是他不支持POST 这里只能服务端处理了 开启跨域权限
在ribbon中添加一个类
package com.axl.blog.conf;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class CorsConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT")
.maxAge();
}
}
加入这个类后 重启 就会开启所有的跨域权限了
下面在任意位置创建一个HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ribbon测试页面</title>
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<!-- 测试项目依赖JQ 目前引用百度公共资源库的资源,如果没有网络环境请自行引入JQ -->
</head>
<body>
<div style="margin-top: 100px;margin-left: 100px">
<button type="button" onclick="oneGet()">一阶GET</button>
<button type="button" onclick="onePost()">一阶POST</button>
</div>
<script type="text/javascript">
function oneGet(){
console.log()
function func(msg){
//var dataObj= eval('(' + msg + ')')
console.log(msg);
}
var method="GET";
var url="http://127.0.0.1:7002/GLOUP-SERVICE/hello";
var data="a=1&b=1"
doAjax(method,url,data,func)
}
function onePost(){
function func(msg){
//var dataObj= eval('(' + msg + ')')
console.log(msg);
}
var method="POST";
var url="http://127.0.0.1:7002/GLOUP-SERVICE/hello";
//var data={"a":1,"b":1}
var data=null;
var saveData = JSON.stringify(data)
console.log(saveData);
doAjax(method,url,saveData,func)
}
function doAjax(method,url,data,func){
if(method=="GET"){
//其他逻辑暂时不做
}else if(method=="POST"){
//其他逻辑暂时不做
}else{
return false;
}
console.log(data);
$.ajax({
type: method,
url: url,
data: data,
dataType:'json',
headers:{
Accept:"application/json",
"Content-Type":"application/json"
},
success: function(msg){
func(msg);
}
});
}
</script>
</body>
</html>
配好地址 运行就可以看结果了,本人实测 POST 和GET请求均能达到预期目的,
最后希望大神多指点~~