springCloud入门学习(二):认识springcloud

一、概念

成都网络公司-成都网站建设公司成都创新互联十年经验成就非凡,专业从事成都网站设计、成都网站建设,成都网页设计,成都网页制作,软文发布平台1元广告等。十年来已成功提供全面的成都网站建设方案,打造行业特色的成都网站建设案例,建站热线:13518219792,我们期待您的来电!

基于springboot基础上用于快速构建分布式系统的通用模式的工具集。

二、特点

1、约定优于配置;

2、隐藏组件复杂性;

3、轻量级组件;

4、组件丰富,功能齐全,例如:服务发现、断路器、微服务网关等;

5、选型中立、丰富;

6、灵活。

三、服务消费者与服务提供者

在微服务架构中有两种角色:服务消费者与服务提供者,二者关系如下:

服务提供者:服务的被调用者

服务消费者:服务的调用者

例如,在电影系统中,用户购买电影票票之前,电影服务需要调用用户服务的接口获取用户信息,此时的电影服务就是调用方,即服务消费者,用户服务为被调用方,即服务提供者。

四、微服务实践

1、服务提供者:用户服务

项目结构如下:

springCloud入门学习(二):认识springcloud

这个demo主要是为了演示服务与服务之间的通信,因此不再配置数据源。

User.java

package com.my.user.entity;

import lombok.Data;

/**
 * @author 垃圾美少女
 */
@Data
public class User {


    private Integer id;
    private String name;
    private Integer age;
    private String username;
    private Integer balance;

}

IUserService.java

package com.my.user.service;

import com.my.user.entity.User;

/**
 * @author 垃圾美少女
 */
public interface IUserService {

    User getByUserId(Integer userId);
}

UserServiceImpl.java

package com.my.user.service.impl;

import com.my.user.entity.User;
import com.my.user.service.IUserService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author 垃圾美少女
 */
@Service
public class UserServiceImpl implements IUserService {

    @Override
    public User getByUserId(Integer userId) {
        List userList = getUserList();
        userList = userList.stream()
                .filter(user -> Objects.equals(user.getId(), userId))
                .collect(Collectors.toList());
        if (userList != null && userList.size() > 0) {
            return userList.get(0);
        }
        return null;
    }

    /**
     * 由于没有配置数据源,在此设置虚拟数据
     *
     * @return list
    */
    private List getUserList() {
        List list = new ArrayList<>(5);
        for (int i = 0; i < 5; i++) {
            User user = new User();
            user.setAge(12 + 1);
            user.setId(1 + i);
            user.setName("用户" + i);
            user.setUsername("用户名" + i);
            user.setBalance(123 + i);
            list.add(user);
        }
        return list;
    }


}

UserController.java

package com.my.user.controller;

import com.my.user.Util.ReturnUtil;
import com.my.user.entity.User;
import com.my.user.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * @author 垃圾美少女
 */
@RestController
@Slf4j
public class UserController {

    @Autowired
    private IUserService userService;


    /**
     * 根据id获取用户信息
     *
     * @param userId 用户id
     * @return map
     */
    @RequestMapping(value = "/user/getUserInfo", method = RequestMethod.GET)
    public Map getUserInfo(Integer userId) {
        try {
            log.info("/user/getUserInfo被访问,参数:userId=" + userId);
            User user = userService.getByUserId(userId);
            return ReturnUtil.succe***esult(user, "获取成功");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ReturnUtil.errorResult(null, "获取失败");
        }
    }


}

ReturnUtil.java

package com.my.user.Util;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 垃圾美少女
 */
public class ReturnUtil {


    public static Map succe***esult(Object data, String msg) {
        Map map = new HashMap<>(3);
        map.put("code", 1);
        map.put("msg", msg);
        map.put("data", data);
        return map;
    }

    public static Map errorResult(Object data, String msg) {
        Map map = new HashMap<>(3);
        map.put("code", -1);
        map.put("msg", msg);
        map.put("data", data);
        return map;
    }


}

application.yml

server:
  port: 8010 #指定端口为  8010

启动项目后访问:http://localhost:8010/user/getUserInfo?userId=1

得到相应:

{
    "msg": "获取成功",
    "data": {
        "id": 1,
        "name": "用户0",
        "age": 13,
        "username": "用户名0",
        "balance": 123
    },
    "code": 1
}

表示接口已通。

2、服务消费者:电影服务

项目架构如下:

springCloud入门学习(二):认识springcloud

User.java和ReturnUtil.java与上例相同在此不再展示。

MovieApplicaiton.java

package com.my.movie;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class MovieApplication {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

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

}

MovieController.java

package com.my.movie.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 垃圾美少女
 */
@RestController
@Slf4j
public class MovieController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping(value = "/movie/findById", method = RequestMethod.GET)
    public Map findById(Integer userId) {
        log.info("/movie/findById被访问,参数:userId=" + userId);
        ResponseEntity forEntity =
                this.restTemplate.getForEntity("http://localhost:8010/user/getUserInfo?userId=" + userId, HashMap.class);
        return forEntity.getBody();

    }

}

application.yml

server:
  port: 8020

此时启动项目,访问:http://localhost:8020/movie/findById?userId=1

得到响应:

{
    "msg": "获取成功",
    "code": 1,
    "data": {
        "id": 1,
        "name": "用户0",
        "age": 13,
        "username": "用户名0",
        "balance": 123
    }
}

至此,一个简单的电影微服务就完成了。

五、上述例子中存在的问题

1、在代码中写死访问路径

在电影服务中,可以将user服务的访问路径写到yml配置文件中,使代码更清爽:

yml:

server:
  port: 8020

userService:
  domain: http://localhost:8010/user/
  getUserByIdUrl: http://localhost:8010/user/getUserInfo?userId=

MovieController.java

package com.my.movie.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 垃圾美少女
 */
@RestController
@Slf4j
public class MovieController {

    @Autowired
    private RestTemplate restTemplate;

    @Value("${userService.domain}")
    private String userServiceDomain;

    @Value("${userService.getUserByIdUrl}")
    private String findByUserIdUrl;

    @RequestMapping(value = "/movie/findById", method = RequestMethod.GET)
    public Map findById(Integer userId) {
        log.info("/movie/findById被访问,参数:userId=" + userId);
        ResponseEntity forEntity =
                this.restTemplate.getForEntity(findByUserIdUrl + userId, HashMap.class);
        return forEntity.getBody();

    }

}

2、适用场景有限:当用户服务的地址或端口号发生改变时,需要修改电影服务的配置文件并且重新部署,这显然是不可取的。


名称栏目:springCloud入门学习(二):认识springcloud
网页地址:http://myzitong.com/article/jddphc.html