天天看点

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

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请求均能达到预期目的,

最后希望大神多指点~~