《深度学习推荐系统实战》 学习笔记 3月Day 13

183 阅读3分钟

09 | 线上服务:如何在线上提供高并发的推荐服务?

一个工业级的推荐服务器内部究竟都做了哪些事情?像阿里、字节、腾讯这样级别的公司,它们的推荐系统是怎么承接住每秒百万甚至上千万的推荐请求的?我们自己该如何搭建一个工业级推荐服务器的雏形呢?

下面就是我们 Sparrow Recsys 中创建推荐服务器的代码,我已经在所有关键的地方添加了注释,你可以逐句解读一下。

public class RecSysServer {
    //主函数,创建推荐服务器并运行
    public static void main(String[] args) throws Exception {
        new RecSysServer().run();
    }
    //推荐服务器的默认服务端口6010
    private static final int DEFAULT_PORT = 6010;


    //运行推荐服务器的函数
    public void run() throws Exception{
        int port = DEFAULT_PORT;
        //绑定IP地址和端口,0.0.0.0代表本地运行
        InetSocketAddress inetAddress = new InetSocketAddress("0.0.0.0", port);
        //创建Jetty服务器
        Server server = new Server(inetAddress);
        //创建Jetty服务器的环境handler
        ServletContextHandler context = new ServletContextHandler();
        context.setContextPath("/");
        context.setWelcomeFiles(new String[] { "index.html" });


        //添加API,getMovie,获取电影相关数据
        context.addServlet(new ServletHolder(new MovieService()), "/getmovie");
        //添加API,getuser,获取用户相关数据
        context.addServlet(new ServletHolder(new UserService()), "/getuser");
        //添加API,getsimilarmovie,获取相似电影推荐
        context.addServlet(new ServletHolder(new SimilarMovieService()), "/getsimilarmovie");
        //添加API,getrecommendation,获取各类电影推荐
        context.addServlet(new ServletHolder(new RecommendationService()), "/getrecommendation");
        //设置Jetty的环境handler
        server.setHandler(context);


        //启动Jetty服务器
        server.start();
        server.join();
    }

你可以看到,创建 Jetty 服务的过程非常简单直观,十几行代码就可以搭建起一套推荐服务。当然,推荐服务的主要业务逻辑并不在这里,而是在每个注册到 Jetty Context 中的 Servlet 服务中。这里我们用其中最简单的 Servlet 服务 MovieService,来看一看 Jetty 中的 Servlet 服务是怎么写的。

//MovieService需要继承Jetty的HttpServlet
public class MovieService extends HttpServlet {
    //实现servlet中的get method
    protected void doGet(HttpServletRequest request,
                         HttpServletResponse response) throws IOException {
        try {
            //该接口返回json对象,所以设置json类型
            response.setContentType("application/json");
            response.setStatus(HttpServletResponse.SC_OK);
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Access-Control-Allow-Origin", "*");
            
            //获得请求中的id参数,转换为movie id
            String movieId = request.getParameter("id");
            //从数据库中获取该movie的数据对象
            Movie movie = DataManager.getInstance().getMovieById(Integer.parseInt(movieId));


            if (null != movie) {
                //使用fasterxml.jackson库把movie对象转换成json对象
                ObjectMapper mapper = new ObjectMapper();
                String jsonMovie = mapper.writeValueAsString(movie);
                //返回json对象
                response.getWriter().println(jsonMovie);
            }else {
                response.getWriter().println("");
            }


        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().println("");
        }
    }

熟悉了这个 Servlet 服务,其他服务就依葫芦画瓢就可以啦。唯一的不同就是其中的业务逻辑。如果你已经从 GitHub 上下载了 Sparrow Recsys 项目把它运行起来,并且在浏览器中输入 http://localhost:6010/getmovie?id=1,就可以看到 getMovie 接口的返回对象了。

小结

这节课我们既学习了怎么“造火箭”,又实践了怎么“拧螺丝”。对于一个合格的算法工程师来说,这两方面缺一不可。“造火箭”的知识包括工业级推荐服务器的具体功能,以及实现工业级高并发推荐服务的主要机制。其中,推荐服务器的具体功能主要有:模型服务、数据库接口、推荐模块逻辑、补充业务逻辑等等,而工业级高并发推荐服务的主要机制有负载均衡、缓存和服务降级。“拧螺丝”的技能我们也掌握了不少,我们利用 Jetty 实践并搭建起了我们 SparrowRecSys 的推荐服务接口。这个过程中,我们需要重点关注的是,每个注册到 Jetty Context 的 Servlet 服务中的主要业务逻辑,只要掌握了一个,在实际工作中我们就能举一反三了。老规矩,我今天继续用表格的形式帮你整理了这节课的主要知识点,你可以看看。
image.png此文章为3月Day25学习笔记,内容来源于极客时间《深度学习推荐系统实战》,强烈推荐该课程!

f90b5d6255252bda60a8c7852aee69a.jpg