Skip to content

Quick Start

Reason94 edited this page Oct 13, 2022 · 16 revisions

1. 非Spring场景(例如Spark,或者更编程化的控制RPC通信)

maven依赖

<dependency>
    <groupId>com.baidu.cloud</groupId>
    <artifactId>starlight-all</artifactId>
    <version>${最新版本}</version>
</dependency>

1.1 不使用protoc编译

Java POJO类定义调用API。用于Java语言间调用,以及跨语言proto文件可手动翻译为Java接口和POJO对象。

a. 为服务端和消费端创建公共接口

跨语言场景按照proto文件定义翻译为Java接口与POJO定义 UserService.java

public interface UserService {
    User getUser(Long userId);
}

b. 服务端编写业务逻辑并启动

编写业务逻辑 UserServiceImpl.java

public class UserServiceImpl implements UserService {
    @Override
    public User getUser(Long userId) {
        User user = new User();
        user.setUserId(userId);
        user.setGender(Gender.MALE);
        user.setMap(Collections.singletonMap("key", new Address("Beijing")));
        return user;
    }
}

启动server DemoProviderApp.java

public class DemoProviderApp {
    public static void main(String[] args) {
        // 初始化server
        TransportConfig transportConfig = new TransportConfig();
        StarlightServer starlightServer = new DefaultStarlightServer("localhost", 8005, transportConfig);
        starlightServer.init();

        // 暴露接口信息
        ServiceConfig serviceConfig = new ServiceConfig();
        starlightServer.export(UserService.class, new UserServiceImpl(), serviceConfig);

        // 开启服务
        starlightServer.serve();

        synchronized (DemoProviderApp.class) {
            try {
                DemoProviderApp.class.wait();
            } catch (Throwable e) {
            }
        }
    }
}

c. 客户端创建并发起调用

DemoConsumerApp.java

public class DemoConsumerApp {

    public static void main(String[] args) {
        // 创建Client
        TransportConfig config = new TransportConfig(); // 传输配置
        StarlightClient starlightClient = new SingleStarlightClient("localhost", 8005, config);
        starlightClient.init();

        // 服务配置
        ServiceConfig clientConfig = new ServiceConfig(); // 服务配置
        clientConfig.setProtocol("brpc");
        // clientConfig.setServiceId("demo.EchoService"); // 跨语言时指定服务端定义的serviceName

        // 生成代理
        JDKProxyFactory proxyFactory = new JDKProxyFactory();
        UserService userService = proxyFactory.getProxy(UserService.class, clientConfig, starlightClient);

        // 发起调用
        User user = userService.getUser(1L);
        System.out.println(user.toString());

        // 销毁client
        starlightClient.destroy();

        System.exit(0);
    }
}

1.2 使用protoc编译

编译proto文件为调用API。特用于客户端跨语言调用时,proto文件复杂无法手动翻译为POJO类。

a. 添加maven插件

按照如下添加并配置protoc-jar-maven-plugin,执行maven compile将proto文件编译为Java类。

    <build>
        <plugins>
            <!--编译proto文件为Java对象-->
            <plugin>
                <groupId>com.github.os72</groupId>
                <artifactId>protoc-jar-maven-plugin</artifactId>
                <version>3.11.4</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <inputDirectories>
                                <!--proto文件存放位置-->
                                <include>src/main/proto</include>
                            </inputDirectories>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

b. 客户端创建公共接口

客户端依照proto文件手写Java接口作为与服务端交互的接口,methodName需与proto文件中一致,接口名不做要求,参数与返回值为上步生成的Java类。

public interface UserProtoService {
    // UserPb.UserProto为proto编译插件生成的类
    // Echo与proto文件定义的方法名一致
    UserPb.UserProto Echo(UserPb.UserProto user);
}

c. 客户端创建并发起调用

public class BrpcProtoConsumer {

    public static void main(String[] args) {

        // 创建Client
        TransportConfig config = new TransportConfig(); // 传输配置
        StarlightClient starlightClient = new SingleStarlightClient("localhost", 8005, config);
        starlightClient.init();

        // 服务配置
        ServiceConfig clientConfig = new ServiceConfig(); // 服务配置
        clientConfig.setProtocol("brpc");
        clientConfig.setServiceId("demo.UserService"); // 跨语言时指定服务端定义的serviceName

        // 生成代理
        JDKProxyFactory proxyFactory = new JDKProxyFactory();
        UserProtoService userService = proxyFactory.getProxy(UserProtoService.class, clientConfig, starlightClient);
     
        // 发起调用
        UserPb.ExtInfoProto extInfoProto = UserPb.ExtInfoProto.newBuilder()
                .setKey("brpckey")
                .setValue("brpcvalue")
                .build();

        UserPb.UserProto user = UserPb.UserProto.newBuilder()
                .setUserId(12L)
                .setUserName("Brpc User")
                .addExtInfos(extInfoProto)
                .build();

        UserPb.UserProto result = userService.Echo(user);
        System.out.println("User result is " + result);
      
        clusterClient.destroy();
        System.exit(0);
    }
}

2. SpringBoot场景(类似Spring MVC)

使用Starlight实现Spring Rest能力,并使用注解暴露与访问Starlight服务。

示例中SpringBootProviderApp单端口对外暴露restful端点与brpc端点,SpringBootConsumerApp通过springrest与brpc协议访问。

maven依赖

<dependency>
    <groupId>com.baidu.cloud</groupId>
    <artifactId>spring-cloud-starter-baidu-starlight</artifactId>
    <version>${最新版本}</version>
</dependency>

a. 创建公共接口并标注restful注解

UserService

不使用rest协议则无需添加@RequestMapping等注解

// 使用com.baidu.cloud.thirdparty中的注解, 不使用rest协议则无需添加
import com.baidu.cloud.thirdparty.springframework.web.bind.annotation.GetMapping;
import com.baidu.cloud.thirdparty.springframework.web.bind.annotation.RequestMapping;
import com.baidu.cloud.thirdparty.springframework.web.bind.annotation.RequestParam;

@RequestMapping("/user")
public interface UserService {
  @GetMapping
  User getUser(@RequestParam("userId") Long userId);
}

b. 服务端编写业务逻辑并启动server

配置信息

starlight:
  server:
    enable: true
    port: 8777

编写业务逻辑 UserServiceImpl

@RpcService // 使用注解暴露服务
public class UserServiceImpl implements UserRestService {
  @Autowire
  private UserService userService;

  @Override
  public User getUser(Long userId) {
    return userService.getUser(userId);
  }
}

启动server

无需额外配置,启动即在单端口上同时暴露restful端点与brpc端点

@SpringBootApplication
@StarlightScan // 作为server使用,扫描@RpcService暴露服务
public class SpringBootProviderApp {

  public static void main(String[] args) {
    SpringApplication.run(SpringBootProviderApp.class, args);
  }
}

c. 客户端注解方式调用服务端

// 启动consumer
@SpringBootApplication
public class SpringBootConsumerApp {

  public static void main(String[] args) {
    SpringApplication.run(SpringBootConsumerApp.class, args);
  }

}
// consumer调用
@RpcProxy(remoteUrl = "localhost:8777", protocol = "brpc") // 使用注解引用服务,指定服务端IP Port,采用brpc协议调用
private UserService userService;

@RpcPorxy(remoteUrl = "localhost:8777", protocol = "springrest") // 使用注解引用服务,指定服务端IP Port,采用springrest(http)协议调用
private UserService restUserService;

public User getUser(Long userId){
        // 发起调用
        restUserService.getUser(userId);
        return userService.getUser(userId);
}

d. curl命令直接调用服务端

curl localhost:8777/user?userId=1

3. SpringCloud场景(完整的微服务应用)

使用consul做注册中心,包含服务发现、负载均衡、集群容错等的微服务应用。

maven依赖

<dependency>
    <groupId>com.baidu.cloud</groupId>
    <artifactId>spring-cloud-starter-baidu-starlight</artifactId>
    <version>${最新版本}</version>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-discovery</artifactId>
    <version>2.0.1.RELEASE</version>
</dependency>

a. 启动consul注册中心

安装consul(官方文档

# 这里以linux为例
wget https://releases.hashicorp.com/consul/1.13.2/consul_1.13.2_linux_amd64.zip
unzip consul_1.13.2_linux_amd64.zip
sudo mv consul /bin

启动consul(官方文档

# 测试模式启动
consul agent -dev

ui后台 http://localhost:8500/ui

b. 为服务端和消费端创建公共接口

public interface UserService {
    User getUser(Long userId);
}

c. 服务端启动并注册

服务端的业务逻辑实现同上SpringBoot场景

配置信息

# 仅展示必要部分
# starlight server
starlight:
  server:
    enable: true
    port: 8999
spring:
  application:
    name: springcloud-demo-provider # 注册服务名
  cloud:
    consul:
      host: localhost # consul注册中心地址
      port: 8500

启动服务

@SpringBootApplication
@EnableDiscoveryClient // 使用注册发现能力
@StarlightScan // 作为server使用,扫描@RpcService暴露服务
public class SpringCloudProviderApp {

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudProviderApp.class, args);
    }
}

d. 客户端发现服务并调用

配置信息

# 仅展示服务发现部分
spring:
  cloud:
    consul:
      host: localhost # consul注册中心地址
      port: 8500

启动服务

@SpringBootApplication
@EnableDiscoveryClient // 进行服务发现
@StarlightScan // 作为server使用,扫描@RpcService暴露服务
public class SpringCloudConsumerApp {

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudConsumerApp.class, args);
    }
}

服务发现与调用

默认的服务发现行为将从localhost:8500发现服务实例

@RpcProxy(name = "springcloud-demo-provider") // 指定服务端名称
private UserService userService;

public User getUser(Long userId) {
    return userService.getUser(userId);
}