• 老平台已死,整理个文档留下做纪念


    1,平台的服务器整体架构

    wps_clip_image-29531

    2,项目结构

    wps_clip_image-32095

    3,业务结构

    wps_clip_image-3913

    4,技术实现

    wps_clip_image-14621

    5,业务举例

    登录页:

    wps_clip_image-3742

    登录:

    wps_clip_image-17

    其它的服务只是业务不同,这里省略...

    6,应用的启动过程资源准备

    wps_clip_image-21766

    7,json的封装

    public static void CrossDomain2(HttpServletResponse response, HttpServletRequest request, Object msg) throws IOException {

            response.setContentType("application/json");

            final String call = request.getParameter("callBack");

            final ObjectMapper mapper = new ObjectMapper();

            String resp = mapper.writeValueAsString(msg);

            if (!Strings.isNullOrEmpty(call)) {resp = call + "(" + resp + ")";}

            PrintWriter out = response.getWriter();

            out.write(resp);

            out.flush();

            out.close(); }

    8,cookie域的算法

    //构造cookie

    final long time = System.currentTimeMillis();

            String userId = String.valueOf(uid);

            String USERINFO = userId + "," + userName + "," + time;

            String u = Base64.encode(USERINFO + "," +

                    buildUserInfoSign(String.valueOf(userId), userName, String.valueOf(time)));

            u = URLEncoder.encode(u, "utf-8");

            String key = URLEncoder.encode(Base64.encode("USERINFO"), "UTF-8");

            Cookie cookie = new Cookie(key, u);

    //构造cookie加密部分

        public static String buildUserInfoSign(String id, String name, String time) {

            String userInfoSrc = id + name + time;

            String key = ConfigurationUtils.get("login.cookieKey");

            String userInfo = userInfoSrc + key;

            String md5UserInfo = MD5Utils.digestAsHex(userInfo);

            return md5UserInfo;

        }

    //解析cookie

    public static int getUserId(HttpServletRequest request) {

            int userId = 0;

            String value = getCookieValueByKey(request);

            if (!Strings.isNullOrEmpty(value)) {

                String val[] = value.split(",");

                userId = Integer.parseInt(val[0]);

            }

            return userId;

    }

    public static String getCookieValueByKey(HttpServletRequest request) {

            String value = "";

            Cookie[] cookies = request.getCookies();

            String name = "USERINFO";

            try {

                name = Base64.encode(name);

                name = URLEncoder.encode(name, "utf-8");

            } catch (Exception e) {

                log.error("USERINFO解码出错!{}", e.getMessage());

            }

            if (cookies != null && cookies.length > 0) {

                for (Cookie cookie : cookies) {

                    String nameStr = cookie.getName();

                    if (nameStr.equals(name)) {

                        value = cookie.getValue();

                        break;

                    }

                }

            }

            if (!Strings.isNullOrEmpty(value)) {

                try {

                    value = URLDecoder.decode(value, "UTF-8");

                    value = Base64.decode2Str(value);

                } catch (Exception e) {

                    log.error("URL解码出错!{}", e.getMessage());

                }

                String val[] = value.split(",");

                String sign = buildUserInfoSign(val[0], val[1], val[2]);

                if (!Strings.isNullOrEmpty(sign) && !Strings.isNullOrEmpty(val[3]) && sign.equals(val[3])) {

                    return value;

                } else {

                    return "";}

            }

            return "";

        }

    9,http的理解和封装

    public class HeadlessServlet extends HttpServlet implements InjectionProxy

    里面加了一个对自定以的注解的过滤;

    protected boolean filters(final HeadlessServletRequest request, final HeadlessServletResponse response) throws ServletException, IOException {

            final Parameter parameter = this.getClass().getAnnotation(Parameter.class);

            if (null == parameter)

                return true;// filter methods

    if (!Strings.isNullOrEmpty(parameter.method()) && !request.getMethod().equalsIgnoreCase(parameter.method())) {

                notFound(response);

                return false;

            }

            // filter parameters

            boolean flag = true, emptyCheck = false;

            try {

                final Map<String, String[]> parameterMap = request.getParameterMap();

                for (String name : parameter.value()) {

                    if (name.endsWith(":")) {

                        name = name.substring(0, name.length() - 1);

                        emptyCheck = true;

                    }

                    flag = parameterMap.containsKey(name);

                    if (emptyCheck) {

                        // must has parameter.

                        flag = flag && parameterMap.get(name) != null;

                        flag = flag && parameterMap.get(name).length > 0;

                        flag = flag && !Strings.isNullOrEmpty(parameterMap.get(name)[0]);

                    }

                    if (!flag)

                        break;

                    emptyCheck = false;

                }

                return flag;

            } finally {

                if (!flag) {

                    response.sendInvalidParameters();

                }

            }

        }

    10,db设计

    wps_clip_image-7341

    11,老平台小结

    老平台采用的架构很简单,一个Guice+Servlet,简单的把一个url映射到一个特定的Servlet,

    这里借用Guice-servlet,省去了原生的servlet配置文件复杂的嫌疑,简单的使用Guice容器,

    把所需资源按照分类和层级一一放到容器中初始化,简化了实例化的过程,提高了效率;业

    务也不复杂,很容易从其它的游戏平台移植过来,业务的技术难点有两个,一个是跟其它服

    务器的交互和通信,另外一个是缓存的使用;对于跟其它服务器的交互,主要是基于http

    请求,如果对这一部分比较熟悉,只要文档给的比较规范,开发和调试起来还是完全没有问

    题的;然后是缓存的问题,这里主要使用的Redis,一个key-value数据库,通过把经常用的

    数据从db中查询出来,放到redis里面,需要的时候从redis里面取得,这大大提升了性能,

    如果redis不稳定,可以直接从db里取得,保证了程序的健壮性;暂未进行过并发性测试,

    目前能支撑2000w用户的使用已经算是一个还不错的架构。

  • 相关阅读:
    当当网css代码
    当当网代码6
    游戏UI设计(2.1)窗口之父CXWnd的封装
    英语(1)备考——词汇
    UML的五类图(UML笔记)
    Sieve of Eratosthenes[ZT]
    std::map初体验
    “非计算机相关专业”的定义
    英语(1)备考——翻译
    使用回调函数发送自定义“消息”
  • 原文地址:https://www.cnblogs.com/snidget/p/3592263.html
Copyright © 2020-2023  润新知