笔记74 微服务笔记1

一、远程调用

  无论是微服务还是SOA,都面临着服务间的远程调用。常见的远程调用方式有两种:RPC和Http

1.RPC(Remote Procedure Call 远程过程调用)

是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序。那么如何实现RPC?

<1>要实现远程调用,肯定需要通过网络传输数据。A程序提供服务,B程序通过网络将请求参数传递给A,A本地执行后得到结果,再将结果返回给程序B。(采用哪种传输协议?传输的数据格式是什么?)

<2>对调用过程进行封装。

注:采用动态代理进行封装。

假设要对UserService中的queryUserById方法进行调用,那么需要定义一个UserService的接口,里面包含方法queryUserById,然后用动态代理来代理这个接口,当有请求调用queryUserById这个方法时,就启用代理,在动态代理的内部建立socket对请求进行接收和发送。

2.HTTP

Http协议:超文本传输协议,是一种应用层协议。规定了网络传输的请求格式、响应格式、资源定位和操作的方式等。但是底层采用什么网络传输协议,并没有规定,不过现在都是采用TCP协议作为底层传输协议。说到这里,大家可能觉得,Http与RPC的远程调用非常像,都是按照某种规定好的数据格式进行网络通信,有请求,有响应。没错,在这点来看,两者非常相似,但是还是有一些细微差别。

二、遇到的问题

1.通用mybatis中,不能使用int,必须使用Integer。

三、实现服务调用

1.use-service-demo:一个提供根据id查询用户的微服务

<1>controller

 1 @RestController
 2 @RequestMapping("user")
 3 public class UserController {
 4 
 5     @Autowired
 6     private UserService userService;
 7 
 8     @GetMapping("/{id}")
 9     public User getOne(@PathVariable("id") Integer id){
10         return userService.queryById(id);
11     }
12 
13 }

<2>service

1 public interface UserService {
2     User queryById(Integer id);
3 }
 1 @Service
 2 public class UserServiceImpl implements UserService {
 3 
 4     @Autowired
 5     private UserMapper userMapper;
 6 
 7     @Override
 8     public User queryById(Integer id) {
 9         return userMapper.selectByPrimaryKey(id);
10     }
11 
12 
13 
14 }

<3>dao

使用第三方插件通用mapper。

1 @org.apache.ibatis.annotations.Mapper
2 @Repository
3 public interface UserMapper extends Mapper<User> {
4 
5 }

<4>pojo

 1 public class User implements Serializable {
 2 
 3     private static final long serialVersionUID = 1L;
 4 
 5     @Id
 6     @GeneratedValue(strategy = GenerationType.IDENTITY)
 7     private Integer id;
 8     private String name;
 9 
10     public Integer getId() {
11         return id;
12     }
13 
14     public void setId(Integer id) {
15         this.id = id;
16     }
17 
18     public String getName() {
19         return name;
20     }
21 
22     public void setName(String name) {
23         this.name = name;
24     }
25 
26     @Override
27     public String toString() {
28         return "User{" +
29                 "id=" + id +
30                 ", name='" + name + '\'' +
31                 '}';
32     }
33 }

2.consumer-demo:一个服务调用者,通过RestTemplate远程调用user-service-demo

先在CunsumerDemoApplication.java注册bean

1  //发送http请求,使用spring的RestTemplate模板工具类
2     @Bean
3     public RestTemplate restTemplate(){
4         return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
5     }

<1>controller

 1 @RestController
 2 @RequestMapping("hello")
 3 public class UserController {
 4     @Autowired
 5     private UserService userService;
 6 
 7 
 8     @GetMapping("/list")
 9     public List<User> queryUsers(@RequestParam("ids") List<Integer> ids){
10        return userService.queryUserByIds(ids);
11     }
12 }

<2>service

 1 @Service
 2 public class UserService {
 3     @Autowired
 4     private UserDao userDao;
 5 
 6     public List<User> queryUserByIds(List<Integer> ids){
 7         List<User> users=new ArrayList<>();
 8         for (Integer id:ids){
 9             User user=this.userDao.queryUserById(id);
10             users.add(user);
11         }
12         return users;
13     }
14 }

<3>dao

 1 @Repository
 2 public class UserDao {
 3     @Autowired
 4     private RestTemplate restTemplate;
 5 
 6     public User queryUserById(Integer id){
 7         String url="http://localhost:8081/user/"+id;
 8         return this.restTemplate.getForObject(url,User.class);
 9     }
10 }

<4>pojo

 1 public class User implements Serializable {
 2 
 3     private static final long serialVersionUID = 1L;
 4 
 5     private Integer id;
 6     private String name;
 7 
 8     public Integer getId() {
 9         return id;
10     }
11 
12     public void setId(Integer id) {
13         this.id = id;
14     }
15 
16     public String getName() {
17         return name;
18     }
19 
20     public void setName(String name) {
21         this.name = name;
22     }
23 
24     @Override
25     public String toString() {
26         return "User{" +
27                 "id=" + id +
28                 ", name='" + name + '\'' +
29                 '}';
30     }
31 }

3.流程图

4.测试

启动服务者和消费者

调用服务

5.存在的问题

    • 在consumer中,我们把url地址硬编码到了代码中,不方便后期维护

    • consumer需要记忆user-service的地址,如果出现变更,可能得不到通知,地址将失效

    • consumer不清楚user-service的状态,服务宕机也不知道

    • user-service只有1台服务,不具备高可用性

    • 即便user-service形成集群,consumer还需自己实现负载均衡

6.分布式服务所面临的问题:

    • 服务管理

      • 如何自动注册和发现

      • 如何实现状态监管

      • 如何实现动态路由

    • 服务如何实现负载均衡

    • 服务如何解决容灾问题

    • 服务如何实现统一配置

四、

posted @ 2018-07-31 13:25  雨落忧伤-  阅读(183)  评论(0编辑  收藏  举报