背景:
在互联网中,随着访问需求的不断扩大,单一的MVC架构已经不能满足用户的访问需求,这个时候就需要RPC分布式或者微服务架构。所以在大型互联网公司中,公司的系统由大量的服务组成,怎样调用服务和怎样为别人提供服务?
RPC请求服务过程:
标注要发布的服务,即服务器提供的服务。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.stereotype.Component;
/**
* RPC annotation for RPC service
* 使用注解标注要发布的服务。
* @author huangyong
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface RpcService {
Class<?> value();
}
服务接口:
/**
* 服务接口。
* @author pc
*
*/
public interface HelloService {
String hello(String name);
String hello(Person person);
}
服务实现:
import com.nettyrpc.test.client.HelloService;
import com.nettyrpc.test.client.Person;
import com.nettyrpc.server.RpcService;
/**
* 服务实现。
* @author pc
* 有注解@RpcService(HelloService.class),会在启动的时候,通过spring的getBeansWithAnnotation获取有这个注解的服务。
* 服务在启动的时候,获取特定注解的Beans集合,扫描所有的服务并得到接口及实现。
*/
@RpcService(HelloService.class)
public class HelloServiceImpl implements HelloService {
@Override
public String hello(String name) {
return "Hello! " + name;
}
@Override
public String hello(Person person) {
return "Hello! " + person.getFirstName() + " " + person.getLastName();
}
}
RPC调用的过程:
client像调用本地方法一样调用服务。
client stub 找到远程服务器地址,调用远程服务。(例如通过Netty的WriteAndFlush方法发送远程调用请求)。
server stub 得到请求后进行解码(decoder)。
server stub调用本地服务获取结果。
server返回结果到server stub中。
server stub发送编码的消息到请求端。
client stub 解码。
client得到结果。
获取一个proxy instance(服务方提供的接口服务),当一个proxy instance的方法激活的时候,会激活与之对应的invoke方法(封装了远程调用的过程),进行实际RPC的调用。
@SuppressWarnings("unchecked")
public static <T> T create(Class<T> interfaceClass) {
return (T) Proxy.newProxyInstance(
interfaceClass.getClassLoader(),
new Class<?>[]{interfaceClass},
new ObjectProxy<T>(interfaceClass)
);
}
// 之后执行RPC远程的提供的服务,会调用invoke方法。
List<Person> persons = personService.GetTestPerson("xiaoming", num);
前面讲了请求服务的过程,怎样发布服务供其他client使用?
发布服务
发布服务通常通过注册的方式,常用的注册服务的方法,比如dubbo通过zookeeper注册、redis注册、simple方式注册。
通过zookeeper注册的方式:可以统一管理地址分配的问题、资源请求均衡负载的问题、选取Master的问题。