Rpc-Server

场景

例如在一个商场系统中,我们将商品库和系统公告两个服务切分开到不同的服务器当中。当用户打开商场首页的时候, 我们希望App向某个网关发起请求,该网关可以自动的帮我们请求商品列表和系统公共等数据,合并返回。

服务定义

每一个Rpc服务其实就一个EasySwoole\Rpc\AbstractService类。 如下:

定义商品服务

  1. namespace App\RpcService;
  2. use EasySwoole\Rpc\AbstractService;
  3. class Goods extends AbstractService
  4. {
  5. /**
  6. * 重写onRequest(比如可以对方法做ip拦截或其它前置操作)
  7. *
  8. * @param string $action
  9. * @return bool
  10. * CreateTime: 2020/6/20 下午11:12
  11. */
  12. protected function onRequest(?string $action): ?bool
  13. {
  14. return true;
  15. }
  16. public function serviceName(): string
  17. {
  18. return 'goods';
  19. }
  20. public function list()
  21. {
  22. $this->response()->setResult([
  23. [
  24. 'goodsId'=>'100001',
  25. 'goodsName'=>'商品1',
  26. 'prices'=>1124
  27. ],
  28. [
  29. 'goodsId'=>'100002',
  30. 'goodsName'=>'商品2',
  31. 'prices'=>599
  32. ]
  33. ]);
  34. $this->response()->setMsg('get goods list success');
  35. }
  36. }

定义公共服务

  1. namespace App\RpcService;
  2. use EasySwoole\Rpc\AbstractService;
  3. class Common extends AbstractService
  4. {
  5. public function serviceName(): string
  6. {
  7. return 'common';
  8. }
  9. public function mailBox()
  10. {
  11. $this->response()->setResult([
  12. [
  13. 'mailId'=>'100001',
  14. 'mailTitle'=>'系统消息1',
  15. ],
  16. [
  17. 'mailId'=>'100001',
  18. 'mailTitle'=>'系统消息1',
  19. ],
  20. ]);
  21. $this->response()->setMsg('get mail list success');
  22. }
  23. public function serverTime()
  24. {
  25. $this->response()->setResult(time());
  26. $this->response()->setMsg('get server time success');
  27. }
  28. }

服务注册

Easyswoole全局的Event文件中,进行服务注册。至于节点管理、服务类定义等具体用法请看对应章节。

  1. namespace EasySwoole\EasySwoole;
  2. use App\RpcService\Common;
  3. use App\RpcService\Goods;
  4. use EasySwoole\EasySwoole\Swoole\EventRegister;
  5. use EasySwoole\EasySwoole\AbstractInterface\Event;
  6. use EasySwoole\Http\Request;
  7. use EasySwoole\Http\Response;
  8. use EasySwoole\Redis\Config\RedisConfig;
  9. use EasySwoole\RedisPool\RedisPool;
  10. use EasySwoole\Rpc\NodeManager\RedisManager;
  11. use EasySwoole\Rpc\Config as RpcConfig;
  12. use EasySwoole\Rpc\Rpc;
  13. class EasySwooleEvent implements Event
  14. {
  15. public static function initialize()
  16. {
  17. // TODO: Implement initialize() method.
  18. date_default_timezone_set('Asia/Shanghai');
  19. }
  20. public static function mainServerCreate(EventRegister $register)
  21. {
  22. /*
  23. * 定义节点Redis管理器
  24. */
  25. $redisPool = new RedisPool(new RedisConfig([
  26. 'host'=>'127.0.0.1'
  27. ]));
  28. $manager = new RedisManager($redisPool);
  29. //配置Rpc实例
  30. $config = new RpcConfig();
  31. //这边用于指定当前服务节点ip,如果不指定,则默认用UDP广播得到的地址
  32. $config->setServerIp('127.0.0.1');
  33. $config->setNodeManager($manager);
  34. /*
  35. * 配置初始化
  36. */
  37. Rpc::getInstance($config);
  38. //添加服务
  39. Rpc::getInstance()->add(new Goods());
  40. Rpc::getInstance()->add(new Common());
  41. Rpc::getInstance()->attachToServer(ServerManager::getInstance()->getSwooleServer());
  42. }
  43. public static function onRequest(Request $request, Response $response): bool
  44. {
  45. // TODO: Implement onRequest() method.
  46. return true;
  47. }
  48. public static function afterRequest(Request $request, Response $response): void
  49. {
  50. // TODO: Implement afterAction() method.
  51. }
  52. }

为了方便测试,我把两个服务放在同一台机器中注册。实际生产场景应该是N台机注册商品服务,N台机器注册公告服务,把服务分开。