SpringCloud初体验:五、Sidecar 将 PHP 这类非 Java 生态语言的服务接入 Spring Cloud
先起一个 Sidecar 服务,一个PHP服务一个应用,和PHP服务部署在同一台机子,通过 localhost 访问,这样就解决了网络开销,相当于本地进程间调用
Sidecar 服务比较简单,
1、这里记录下 maven 的配置
<?xml version="1.0" encoding="UTF-8"?> <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>cn.taxiong</groupId> <artifactId>tx_php_server_side_car</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>tx_php_server_side_car</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <!--配置仓库--> <repositories> <repository> <id>aliRepository</id> <name>aliRepository</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <!-- cloud --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Finchley.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-netflix-sidecar</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2、sidecar 相关的配置,及注册中心的配置
spring: application: name: tx-php-server-sidecar #服务注册中心端口号 server: port: 8203 #服务注册中心实例的主机名、端口 #是否向服务注册中心注册自己 #是否检索服务 #服务注册中心的配置内容,指定服务注册中心的位置 eureka: port: 8200 instance: hostname: localhost client: register-with-eureka: true fetch-registry: true serviceUrl: defaultZone: http://${eureka.instance.hostname}:${eureka.port}/eureka/ sidecar: port: 1215 instance: hostname: localhost health-uri: http://${sidecar.instance.hostname}:${sidecar.port}/health
3、服务启动类 @EnableSidecar
4、还需要在PHP服务一个检查服务的接口或文件, 注意响应头类型 Content-Type
以 laravel 框架为例子,配置后的地址是 http://127.0.0.1:1215/health
Route::get('health', function () { $content = '{ "status" : "UP" }'; $status = 200; $value = 'application/json; charset=utf-8'; return response($content, $status) ->header('Content-Type', $value); });
这是通过 Eureka 中心页面,看见 Sidecar 已经注册上去,注意如果 PHP 的 health 页面的响应内容或者响应头不对的话, Sidecar 服务的 UP 状态会显示 DOWN
这里是 PHP 服务的默认页面
这里是通过 Spring Cloud gateway 转发后的 PHP 服务页面
服务间调用
一、PHP 服务调用 Java 服务的用法(调用host地址是Sidecar的地址,URi为服务名加接口地址,URi的拼装和Feign一样)
<?php /** * Created by PhpStorm. * User: liugx * Date: 2018/9/9 * Time: 下午12:57 */ namespace App\Http\Controllers; use App\Exceptions\BusinessException; use GuzzleHttp\Client; class TestController extends Controller { /** * @return \Psr\Http\Message\StreamInterface * @throws BusinessException */ public function test() { // Sidecar的端口号(本地调用) $host = 'http://localhost:8203'; // 注册到Eureka的服务名称 $javaServiceName = 'tx-java-server'; // 要调用服务的接口URL $func = '/'; // 通过Sidecar调用服务的URL $uri = "/{$javaServiceName}{$func}"; $base_uri = $host; $client = new Client([ // Base URI is used with relative requests 'base_uri' => $base_uri, 'timeout' => 3.0, ]); $params = []; try { $response = $client->request('GET', $uri, [ 'query' => $params ]); } catch (\GuzzleHttp\Exception\GuzzleException $ex) { throw new BusinessException("抱歉,网络异常:{$ex->getMessage()}"); } return $response->getBody(); } }
二、Java 服务调用 PHP 服务的用法
直接用FeignClient做服务间调用
SpringCloud初体验:三、Feign 服务间调用(FeignClient)、负载均衡(Ribbon)、容错/降级处理(Hystrix)