但基于HTTP协议的KoleosPC质量却不如基于TCP协议的奥迪Q5PC,永利官方网站通俗的语言表明什么是 冠道PC

永利官方网站 1

现阶段广大使用应该都不是one in
all情势了,幸免不了发生远程调用,和共事聊了下宝马X3PC之后,发现我们对哈弗PC的概念如故比较模糊的,纵然平素在用,不过不太明白其含义,在网易上搜了下陆风X8PC
HTTP那俩个关键词,发现如故有很多误解的。

RPC是什么?

深远浅出的讲就是,调用远程总括机上的服务,就像是调用本地服务一样。平常包蕴传输协议和编码协议。

ENVISIONPC可以根据HTTP或TCP协议,但基于HTTP协议的EscortPC质量却不如基于TCP协议的奥德赛PC。两上边会直接影响SportagePC的属性,一是传输方式,二是连串化。

肯定,TCP是传输层协议,HTTP是应用层协议,而传输层较应用层特别底层,在多少传输方面,越底层越快,因而,在形似情状下,TCP
一定比HTTP快。就系列化而言,Java
提供了默认的种类化格局,但在高并发的情景下,那种措施将会带来一些性质上的瓶颈,于是市面上出现了一多元可以的体系化框架,以替代
Java 暗中同意的体系化,从而提供更迅捷的习性。

  • 题材一:既然有http 请求,为何还要用rpc调用?
  • 标题二:请问rpc协商和http协议的涉及和区分?

ENVISIONPC和HTTP有哪些关系?

  1. HTTP自个儿也得以当作HavalPC的传输层协议

  2. 和HTTP相比较,TCP极大的简洁了传输内容

  3. 半数以上奥德赛PC框架是面向服务的卷入,针对服务的可用性和功能等都做了优化

  4. 架在劳务治理、总管均等方面做了很好的支撑

  5. 个中服务一般走中华VPC,外部服务一般走HTTP

然后就萌生了写一篇有关奥迪Q3PC的篇章。

其它

越底层,代码越繁杂、灵活性越高、效用越高;越上层,抽象封装越好、代码越不难、功效越差。

专营商的扑朔迷离技术须求常常对于远程调用需求达成包蕴但不断以下两种须求
(1)
路由计划、服务治理。调用的下游服务处在重启、扩容或然有些机器下线,须要马上关门对应机器的流量,防止造成不可用。
调整流量的路由策略。
(2)
负载均衡。将流量平均打到下游服务的有所机器上
(3)
服务降级、自动熔断。当下游服务调用错误率明显抓好后,及时熔断幸免影响上游服务,服务復苏后立刻过来流量。

 

SOAP是HTTP+文本

 参考:http://blog.jobbole.com/92290/

 

① 、SportagePC的基本概念

揽胜极光PC,即 Remote Procedure
Call(远程进程调用),说得通俗一点就是:调用远程计算机上的劳动,如同调用本地服务均等。
瑞鹰PC的完结包涵了两局地,一部分是客户端,一部分是服务端,服务的调用方发送大切诺基PC请求到服务提供方,服务提供方依据参数执行办法,响应客户端,一次哈弗PC请求停止。
那篇小说解释的正确性:开始的言语表明什么是 中华VPC
框架

永利官方网站 2

image.png

大切诺基PC 可依照 HTTP 或 TCP 协议,Web Service 就是依据 HTTP 协议的
陆风X8PC,它抱有非凡的跨平台性,但其品质却不如基于 TCP 商谈的
QX56PC。会两地点会向来影响 帕杰罗PC 的品质,一是传输方式,二是种类化。

明朗,TCP 是传输层协议,HTTP
是应用层协议,而传输层较应用层尤其底层,在数量传输方面,越底层越快,由此,在相似景况下,TCP
一定比 HTTP 快。就连串化而言,Java
提供了私自认同的体系化格局,但在高并发的意况下,那种格局将会推动一些质量上的瓶颈,于是市面上出现了一名目繁多可以的体系化框架,比如:Protobuf、Kryo、Hessian、杰克逊等,它们得以取代 Java 暗中同意的连串化,从而提供更快捷的习性。

本着对象种类化,有各类艺术的天性比较,Github地址:

永利官方网站 3

image.png

通过对照可以:

  • 谷歌的Protostuff质量最好
  • JSON/XML质量比较差

可是JSON/XML格局在网络领域应用相比宽泛,第叁方的剖析包也相比较不难接纳,所以在功效须要不是很高的事态下是一种科学的选项。

dubbo作为一种服务治理框架,PAJEROPC作为内部的中间通讯方式,使用也是十三分容易:

@Component
public class CityDubboConsumerService {

    @Reference(version = "1.0.0")
    CityDubboService cityDubboService;

    public void printCity() {
        String cityName="xx";
        City city = cityDubboService.findCityByName(cityName);
        System.out.println(city.toString());
    }
}
  • 在不通晓TucsonPC概念的情况下,会觉得RAV4PC就只有那种使用,其实开发中时时应用的HTTPClient调用也是属于途观PC的一种艺术。

二、RPC的使用

一 、基于TCP的长途调用

  • 劳务消费者

public class Consumer {


    public static void main(String[] args) throws UnknownHostException, IOException, SecurityException, NoSuchMethodException, ClassNotFoundException{

        //接口名称
        String interfacename= SayHelloService.class.getName();

        //需要远程执行的方法
        Method method = SayHelloService.class.getMethod("sayHello", java.lang.String.class);

        //需要传递到远端的参数
        Object[] arguments = {"hello"};

        Socket socket = new Socket("127.0.0.1", 1234);

        //将方法名称和参数传递到远端
        ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
        output.writeUTF(interfacename); //接口名称
        output.writeUTF(method.getName());  //方法名称
        output.writeObject(method.getParameterTypes());
        output.writeObject(arguments);

        //从远端读取方法执行结果
        ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
        Object result = input.readObject();

        //使用代理对象来处理,直接返回string类型

        System.out.println(result);
    }
}
  • 服务提供者

public class Provider {

    //所有的服务
    private static Map<String,Object> services = new HashMap<String,Object>();

    static{
        services.put(SayHelloService.class.getName(), new SayHelloServiceImpl());
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{

        ServerSocket server = new ServerSocket(1234);
        while(true) {
            Socket socket = server.accept();

            //读取服务信息
            ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
            String interfacename = input.readUTF(); //接口名称
            String methodName = input.readUTF();  //方法名称
            Class<?>[] parameterTypes = (Class<?>[])input.readObject();  //参数类型
            Object[] arguments = (Object[])input.readObject();  //参数对象

            //执行调用
            Class serviceinterfaceclass = Class.forName(interfacename);//得到接口的class
            Object service = services.get(interfacename);//取得服务实现的对象
            Method method = serviceinterfaceclass.getMethod(methodName, parameterTypes);//获得要调用的方法
            Object result = method.invoke(service, arguments);

            ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
            output.writeObject(result);
        }
    }
}
  • 接口

public interface SayHelloService {

    /**
     * 问好的接口
     * @param helloArg 参数
     * @return
     */
    public String sayHello(String helloArg);
}
  • 实现类

public class SayHelloServiceImpl implements SayHelloService {

    @Override
    public String sayHello(String helloArg) {

        if(helloArg.equals("hello")){
            return "hello";
        }else{
            return "bye bye";
        }

    }

}

贰 、基于HTTP的长途调用

  • 基础服务接口

public interface BaseService {

    public Object execute(Map<String,Object> args);
}
  • JSON结果集

public class JsonResult {

    //结果状态码
    private int resultCode;
    //状态码解释消息
    private String message;
    //结果
    private Object result;

    public int getResultCode() {
        return resultCode;
    }
    public void setResultCode(int resultCode) {
        this.resultCode = resultCode;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public Object getResult() {
        return result;
    }
    public void setResult(Object result) {
        this.result = result;
    }
}
  • JSON帮助类

public class JsonUtil {

    private static final ObjectMapper mapper = new ObjectMapper();

    public static Object jsonToObject(String json, Class cls) {

        try{
            //允许json串里面的key value不带双引号
            mapper.configure(org.codehaus.jackson.JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);

            // 允许制定的object中的属性没有json串中某个key
            mapper.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

            return mapper.readValue(json, cls);

        }catch(Exception e){}

        return null;

    }

    public static String getJson(Object object)  {

        try{
            String json = null;

            StringWriter sw = new StringWriter();
            JsonGenerator gen = new JsonFactory().createJsonGenerator(sw);
            mapper.writeValue(gen, object);
            gen.close();
            json = sw.toString();
            return json;

        }catch(Exception e){}

        return null;
    }
}

public class SayHelloService implements BaseService{

    public Object execute(Map<String, Object> args) {
        //request.getParameterMap() 取出来为array,此处需要注意
        String[] helloArg = (String[]) args.get("arg1");

        if("hello".equals(helloArg[0])){
            return "hello";
        }else{
            return "bye bye";
        }
    }

}
  • 服务消费者

public class ServiceConsumer extends HttpServlet{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        //参数
        String service = "com.http.sayhello";
        String format = "json";
        String arg1 = "hello";


        String url = "http://localhost:8080//testhttprpc/provider.do?"+"service=" + service + "&format=" + format + "&arg1=" + arg1;

        //组装请求
        HttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);

        //接收响应
        HttpResponse response = httpClient.execute(httpGet);

        HttpEntity entity = response.getEntity();
        byte[] bytes = EntityUtils.toByteArray(entity);
        String jsonresult = new String(bytes, "utf8");

        JsonResult result = (JsonResult)JsonUtil.jsonToObject(jsonresult, JsonResult.class);

        resp.getWriter().write(result.getResult().toString());

    }
}
  • 劳动提供者

public class ServiceProvider  extends HttpServlet{

    private Map<String,BaseService> serviceMap ;


    @Override
    public void init() throws ServletException {
        //服务map初始化
        serviceMap = new HashMap<String,BaseService>();
        serviceMap.put("com.http.sayhello", new SayHelloService());
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        //基本参数
        String servicename = req.getParameter("service");
        String format = req.getParameter("format");

        Map parameters =  req.getParameterMap();

        BaseService service = serviceMap.get(servicename);
        Object result = service.execute(parameters);

        //生成json结果集
        JsonResult jsonResult = new JsonResult();
        jsonResult.setResult(result);
        jsonResult.setMessage("success");
        jsonResult.setResultCode(200);

        String json = JsonUtil.getJson(jsonResult);
        resp.getWriter().write(json);
    }
}

3、URL风格

  • RPC风格的URL
  • RESTFUL风格的URL

RPC风格的URL
http://hostname/provider.do?service=com.http.sayhello&format=json&timest amp=2017-04-07-13-22-09&arg1=arg1&arg2=arg2

  • hostname表示服务提供方的主机名
  • service代表远程调用的服务接口名称
  • format表示回去参数的格式
  • timestamp代表客户端请求的岁月戳
  • arg1和 arg2象克服务所须求的参数
  • 备考:Tmall开放平台的API以这种格局的U兰德酷路泽L提供

RESTFUL风格的URL

POST http://hostname/people 创建name为zhangsan的people记录
GET http://hostname/people/zhangsan 返回name为zhangsan的people记录
PUT http://hostname/people/zhangsan 提交name为zhangsan的people记录更新 
DELETE http://hostname/people/zhangsan 删除name为zhangsan的people记录

三、总结

  • 正文内容部分摘自《大型分布式网站架构》

相关文章