demand

After understanding the necessity for service governance to emerge as we mentioned earlier. We know that service governance is based on many “services”, so the first step is to get through these services is the foundation, which is often referred to as RPC remote calls. Call a method on a remote server as if it were a local method.

Now let’s introduce a requirement in a simple colloquial way:

In the project deployed on server A, there is A UserService that has A getUserInfo method inside it. B server wants to call this method “directly”, what to do?

Analysis of the

Let’s take PHP as an example. We want to implement A direct invocation on server B similar to that on server A



$userService = new UserService();
$userService->getUserInfo($uid);Copy the code

We often use SDKS to call API services provided by third parties, and our approach is definitely similar



$client  = new \SDK\Client();
$request = new \SDK\UserService\Request\GetStudentInfoRequest();
$request->setUid($uid);
$request->setMethod("GET");
$response = $client->doAction($request);Copy the code

GetStudentInfoRequest in SDK maps UserService::getUserInfo on server A via HTTP.

Reconstruction of the SDK

We only need to modify the original, the following code is a simple demonstration

The service side

The service is deployed at localhost:8081



class UserService
{
    public static function getUserInfo($uid)
    {
        // Assume that the following content is fetched from the database
        return [
            'id'       => $uid,
            'username'= >'mengkang',]; } } $service = $_GET['service'];
$action = $_GET['action'];
$argv = file_get_contents("php://input");

if(! $service || ! $action) {die(a); }if ($argv) {
    $argv = json_decode($argv, true);
}


$res = call_user_func_array([$service, $action], $argv);

echo json_encode($res);Copy the code

The client



class Client
{
    private $url;
    private $service;

    private $rpcConfig = [
        "UserService"= >"http://127.0.0.1:8081",];/**
     * Client constructor.
     * @param $service
     */
    public function __construct($service)
    {
        if (array_key_exists($service, $this->rpcConfig)) {
            $this->url = $this->rpcConfig[$service];
            $this->service = $service; }}public function __call($action, $arguments)
    {


        $content = json_encode($arguments);
        $options['http'] = [
            'timeout'= >5.'method'= >'POST'.'header'= >'Content-type:application/x-www-form-urlencoded'.'content' => $content,
        ];

        $context = stream_context_create($options);

        $get = [
            'service'= >$this->service,
            'action'  => $action,
        ];

        $url = $this->url . "?" . http_build_query($get);

        $res = file_get_contents($url, false, $context);

        return json_decode($res, true);
    }

}

$userService = new Client('UserService');
var_export($userService->getUserInfo(103));Copy the code

Isn’t it convenient to call remote methods on the client as if they were local? That’s how @Laruence Yar operates.

Yar demo

Client code, assuming the service is located on LAN 10.211.55.4



class RpcClient {
    // RPC service address mapping table
    public static $rpcConfig = array(
        "RewardScoreService"= >"http://10.211.55.4/yar/server/RewardScoreService.class.php",);public static function init($server){
        if (array_key_exists($server, self::$rpcConfig)) {
            $uri = self::$rpcConfig[$server];
            return new Yar_Client($uri);
        }
    }
}
 
$RewardScoreService = RpcClient::init("RewardScoreService");
var_dump($RewardScoreService->support(1.2));Copy the code

Server-side code



class RewardScoreService {
    /** * $uid give $feedId a like *@param $feedId  interge
     * @param $uid  interge
     * @return void
     */
    public function support($uid,$feedId){
        return "uid = ".$uid.", feedId = ".$feedId;
    }
}
 
$yar_server = new Yar_server(new RewardScoreService());
$yar_server->handle();Copy the code

The story behind Yar is my code demo above. At this point, the RPC framework becomes less mysterious. Of course this is just an implementation of RPC in PHP. After all, PHP is the best language in the world.

Java remote Call

It’s a little more difficult to switch to Java, which feels more localized when implemented, so Java is the most powerful language. Since Java is compiled statically, there is no way to implement remote calls like PHP’s __call method, which is usually implemented through dynamic proxies



import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
/** * Created by zhoumengkang on 5/12/15. */
 
/** ** Points service interface */
interface RewardScoreService{
    String support(int uid,int feedId);
}
 
public class SupportService {
 
    public static void main(String[] args) {
        add(1.2);
    }
 
    /** * uid give feedId a like *@param uid
     * @param feedId
     * @return* /
    public static String add(int uid, int feedId){
        YarClient yarClient = new YarClient();
        RewardScoreService rewardScoreService = (RewardScoreService) yarClient.proxy(RewardScoreService.class);
        returnrewardScoreService.support(uid, feedId); }}class YarClient {
 
    public final Object proxy(Class type) {
        YarClientInvocationHandler handler = new YarClientInvocationHandler();
        return Proxy.newProxyInstance(type.getClassLoader(), newClass[]{type}, handler); }}final class YarClientInvocationHandler implements InvocationHandler {
 
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Dynamic calls here implement PHP's __call method.");
 
        System.out.println("method : " + method.getName());
        for (int i = 0; i < args.length; i++) {
            System.out.println("args["+ i +"]." + args[i]);
        }
         
        return null; }}Copy the code

To learn more

After reading this article, does the RPC framework suddenly feel a little less mysterious?

Old iron weekend live: unveiled her mysterious veil – zero base to build their own service governance framework get on the bus segmentfault.com/l/15…