spring cloud踩坑日志(5)- ribbon的简单应用

来源:互联网 发布:iphone的看书软件 编辑:程序博客网 时间:2024/06/02 04:27

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@SpringBootApplicationpublic 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;@Configurationpublic class CorsConfig extends WebMvcConfigurerAdapter {    @Override    public void addCorsMappings(CorsRegistry registry) {        registry.addMapping("/**")                .allowedOrigins("*")                .allowCredentials(true)                .allowedMethods("GET", "POST", "DELETE", "PUT")                .maxAge(3600);    }}

加入这个类后 重启 就会开启所有的跨域权限了

下面在任意位置创建一个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(1)            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请求均能达到预期目的,

最后希望大神多指点~~