前后端分离实践(EOS篇)

1.简介

    作为后端,在整个java的环境中,服务的RPC操作是分布式应用中至关重要的部分,如何让开发人员无成本的接入分布式架构,这是我们在思考的范畴。引入它让我们使用java开放服务轻而易举,规范服务接口标准以及跨语言的服务调用提供了快捷途径~

1.1 EOS设计原则

    它的核心是接口,希望能有效减少开发资源等待的弊端。

  • 规范接口,接口要求前端,后端,测试人员都能看懂,能用。而且接口是直接引用到我们的程序中,任何更改都有相关的记录,相关人员的审核。        

  • 接口的可测试性。由测试人员直接介入到接口的测试中来,首先保证接口的正确性,给后面的联调工作带来无法估量的好处,理想情况一次通过。而且测试人员可以直接判断错误的来源,到底是前端还是后端            

  • 前端人员不用等待后端的开发,接口中就规定了模拟报文,前端人员直接开发,而且后面联调时代码也不需要调整,只需要更改一个参数,就可以自动切换到后端程序。            

  • 前端,后端,测试各司其职,互不影响,很好体现了解耦的思想        

  • 后端开发人员技术上跟现在没有变化,技术门槛低,直接开发到Spring的服务层就可以了,采用单元测试,更快提高效率        

1.2 角色职责

    定义的职责是大部分跟接口相关的,得接口得天下。        

  • java后端开发程序员:和前端人员沟通,定义接口;不能私自更改接口,有更改必须更相关的前端人员沟通;对一些重要的调整,请跟小组长联系;

  • 前端开发人员:参与定制接口;

  • 小组长:检查程序员接口的规范性,是否存在没必要的冗余;协助程序员和前端人员的沟通;直接参与一些重要模块的接口定制;切实起到小组长的作用,在做审批接口的时候,最好能够做代码审查,包括单元测试是否完备。

  • 测试人员:参与到接口的测试中来;以后技能提升了以后,可以直接参与单元测试(我们考虑开发一些工具(API),实现自动测试);有一个不成熟想法,前端,后端各自提交成果测试,测试完成后,由测试这边统一联调(个人认为基本上工作量不会很大了)。

1.3 系统组成

    eos包含以下几部分:

  • 服务提供端Server:后端开发者重点关注,根据提供的eos-server.jar包开发应用。

  • 中心管理端:包含控制端eos程序和界面配置端uddi程序。也是直接部署即可。

  • 客户端Client:前端开发者重点关注,根据eos-client.jar包和jquery.eosremote.js开发应用。

  • zookeeper:此程序为第三方应用直接下载部署即可,它是整个系统的强依赖,提供服务端服务信息注册,提供eos管理端在线注册。

  •     系统的组成部署图如下:142749_qQC3_167767.png

1.4 系统执行流程

    服务端发布服务,挂接到eos,客户端取得挂接有需要调用的服务的eos地址进行服务请求,eos对请求进行过滤代理请求服务端服务数据,返回给客户端,具体图解如下:   142818_FSjT_167767.png          

    可见,多了模拟数据获取的支持,eos轻松实现前后端分离开发,两端不需要同步等待。并且,系统采用分布式思想,可以部署多台服务端和eos中心端以及客户端,轻松实现平行扩展。


2.快速开始

2.1 核心部件部署

(1)zookeeper:此程序为第三方应用直接下载部署即可。

(2)中心管理端:包含控制端eos程序和界面配置端uddi程序。也是直接部署即可。注意根据配置文件说明更改对应参数即可。        

    eos程序的配置eos.properties:

#zookeeper服务端的ip地址
zookeeper_ip=192.168.0.224
zookeeper_port=2181
#eos的标识,服务端挂接服务需要知道此id
eos_id=ulyn
#client能够访问到eos的本机ip地址
local_ip=192.168.0.60
#服务请求的端口号,默认值为5555
eos_port=5555
#eos的模式,默认是为pro部署模式,当为dev开发模式,开发模式允许mock模拟,否则不管客户端是否指定mock请求都直接调用真实服务
eos_mode=dev

2.2 服务端开发

(1)申请应用接入:访问uddi管理界面,注册应用,取得appid,例如:ihome    

(2)可以使用eos-server-example工程    

(3)制定服务接口:根据项目功能需求制定java接口类Test.java,见3.2.1

(3)在uddi管理中进行接口java文件上传,由小组长审核        

(4)实现接口类

(5)修改配置文件eos-server.properties参数,启动系统

#zookeeper服务端的ip地址
zookeeper_ip=192.168.0.224
zookeeper_port=2181
#挂接的eos_id,挂接多个eos请使用逗号隔开
eos_id=ulyn
#eos能够连接到server的本机ip
local_ip=192.168.0.60
#netty服务器的端口,默认是5555
netty_server_port=10085
#应用id
app_id=ihome

2.3 客户端开发

(1)在uddi管理中下载接口java文件Test.java,下载得接口文件如下:

package com.sunsharing.component.test;
import com.sunsharing.eos.common.annotation.ParameterNames;

import com.sunsharing.eos.common.annotation.EosService;

@EosService(version="1.0",appId="ihome",id="test")
public interface Test {
    /**
     * 说hello
     * @param abc
     * @return
     * ${ulyn}
     * ulyn
     */
@ParameterNames(value = {"abc"})
    String sayHello(String abc);

}

(2)使用eos-client-example工程,将接口放对应的包路径com.sunsharing.component.test,即下载的java文件的package。

(3)java使用者直接使用接口:

 Test test = ServiceContext.getBean(Test.class);
 test.sayHello("hello");

(4)前端,使用js辅助插件jquer.eosremote.js,依赖jquery.js和json2.js

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
<script type="text/javascript" src="/js/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="/js/json2.js"></script>
<script type="text/javascript" src="/js/jquery.eosremote.js"></script>
<script>
    $(document).ready(function () {
        $.eosRemote({
            url: "/remote",
            serviceId: "test",
            mock: "hexin",
            method: "sayHello",
            data: {"abc": "hello"},
            success: function (data) {
                alert("返回结果:" + data);
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                alert(errorThrown);
            }
        });
    });
</script>
</body>
</html>

(5)修改配置文件eos-client.properties参数,启动系统    

zookeeper服务端的ip地址
zookeeper_ip=192.168.0.224
zookeeper_port=2181
#联调服务端ip,当有配置次参数时,可以指定从此server取得数据,不配置则走负载均衡随机取得一台服务
#debugging_server_ip=192.168.100.60
#全局控制是否使用mock,默认值为false
use_mock=false


3.使用说明

3.1 中心管理端

3.1.1 控制端eos

    对于此系统,部署启动即可。jar包执行类为com.sunsharing.eos.manager.main.Eos,可以使用发包提供的批处理命令启动。

    它作为客户端桥,调用服务端接口,主要实现以下流程:                            

  • (1)判断是否审批通过,不通过则不继续往下处理,直接返回服务未通过审核异常 

  • (2)判断是否需要测试模拟,是模拟则直接返回模拟测试数据,不继续往下处理 

  • (3)调用实际server服务  

  • (4)调用监控逻辑                                                      

    在此特别需要强调的是配置文件eos.properties,     约定配置文件的第一行请不要配置参数(因为使用校验框架resvalidate,下面的server和client也遵循此约定)。重点关注下eos_mode配置项,它是配置eos的模式,不配置则使用默认值pro部署模式,dev为开发模式,开发模式允许mock模拟。也就是说,当客户端client处指定请求mock数据时,我们eos会根据eos_mode来最终决定给模拟数据还是实际调用数据。假如eos_mode=pro,无论client是否指定mock,都返回实际调用数据。

3.1.2 界面配置端uddi

    对于此系统,部署启动即可。可以使用发包提供的批处理命令启动也可以部署在web容器使用。                            

  • 提供服务接口的上传发布并进行审核、下载。

  • 直观显示服务状态

    此部分使用一看系统界面便懂,略过。。。

3.2 服务提供端Server

3.2.1 制定服务接口

    根据项目功能需求制定java接口类,按照如下规约:

(1)接口类有@EosService的注解

(2)对于注解需要配置version参数,接口升级需要升级version参数                            

(3)对于注解,id参数默认不需要配置,值为类名第一个字母小写,一个应用不能有相同的id的服务

(4)请不要使用方法的重载,也就是说方法函数名不要重复                            

(5)请使用常用java类型,int,boolean,String,Map,List等,请不要使用自定义POJO类,如User、Animal....

(6)接口方法详细根据javadoc进行注释                            

(7)配置mock参数,作为模拟测试用的返回值。写在javadoc注释的@return,每一种mock使用${}紧接描述,接着空一行写模拟值,模拟值使用json格式(简单类型直接写值,对象用{}格式,数组对应[]格式)。如:

   /**
     * 取得num条List
     *
     * @param num
     * @return ${success}当入参name="criss"为成功输出
     *         [{"success":"成功了2",
     *         "haha":"haha2"}]
     *         ${error}当入参为其他时为错误输出
     *         [{"error":"错误了2"}]
     */
    List getList(int num);

3.2.1 暴露服务端

    在服务端系统启动处加入启动代码:

com.sunsharing.eos.server.EosInit.start(ctx,"com.sunsharing");

    ctx为Spring的ApplicationContext,也就是说服务接口如果是有Spring实现的,必须在启动初始化时候入参传入。上述代码意思是将在com.sunsharing扫描服务接口并进行注册等事件。

服务端开发在于对接口的实现,当接口有多种实现时,系统只默认取一个实现方式,所以,请尽量 不要有接口的多种实现。如果确实有多种接口,请指定,否则可能取的不是你想要的实现方式。指定可以使用配置文件EosServiceConfig.xml,主要在于impl,也就是服务的实现类,当实现类有多种,可以指定一种实现。格式如下:

<beans>
    <bean id="beanId" impl="com.sunsharing.eos.server.test.TestService"/>
</beans>

3.3 客户端Client

    对于客户端的使用,支持两种方式,java client和js client。当然,使用的接口均是服务端制定出来的,从uudi系统下载的接口文件。将下载的服务接口文件放在工程相应的位置,对于要快速开发使用的可以直接使用eos-client-example工程,请确保服务接口一定是从uudi系统下载下来的,并且不去更改它。

3.3.1 基本功能使用

    在客户端端系统启动处加入启动代码进行接口初始化:

com.sunsharing.eos.client.EosInit.start("com.sunsharing");

    java使用者直接使用接口:                  

Test test = ServiceContext.getBean(Test.class);
 test.sayHello("hello");

    前端,使用js辅助插件jquer.eosremote.js进行接口调用,依赖jquery.js和json2.js,系统需要在web.xml文件中配置Servlet提供js请求,配置代码如下:

<servlet>
        <description>remote servlet</description>
        <display-name>remote servlet</display-name>
        <servlet-name>remoteServlet</servlet-name>
        <servlet-class>com.sunsharing.eos.client.RpcServlet</servlet-class>
        <init-param>
            <param-name>scanPackage</param-name>
            <param-value>com.sunsharing</param-value>
        </init-param>
        <init-param>
            <param-name>sysParamVar</param-name>
            <param-value>com.sunsharing.component.sys.ParamVarImpl</param-value>
        </init-param>
        <load-on-startup>0</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>remoteServlet</servlet-name>
        <url-pattern>/remote</url-pattern>
    </servlet-mapping>

    下面对上述配置进行说明:

(1)scanPackage:表示eos-client初始化时候扫描的服务接口的路径,同EosInit.start("com.sunsharing");。所以当有进行RpcServlet配置时,在系统启动不需要再写EosInit.start进行初始化。当然,写了也不会重复初始化。

(2)sysParamVar:配置系统变量获取com.sunsharing.eos.client.sys.SysParamVar的实现类,该实现类需要开发者自行编写,可以根据变量名取得系统缓存的变量的值。此类是为了支持js入参值为${}变量形式获取的接口,当入参为后台变量形式,如入参userId=${userId},那么后台java端将使用该实现类取得userId的值。

    jquery.eosremote.js使用参数说明:它借鉴jquery ajax使用的格式,特别的,前端提出的一个需求,前端开发使用跨域取值请求,而实际整合联调项目时走正常同域请求,因此开发时候可以修改下jquery.eosremote.js文件的dataType参数为jsonp即可实现跨域,当实际联调时候再改回json。

PropertyTypeDefaultDescription
urlString"/remote"RpcServlet配置的请求地址
serviceIdString''调用服务id
methodString''调用服务的方法
mockString""指定要获取的模拟的数据值,对应接口文件的@return的${}
dataObjectnull方法入参值
beforeSendfunctionfunction (XHR) {     }发送请求前
successfunctionfunction (data, textStatus) {     }请求成功后
errorfunctionfunction (XMLHttpRequest, textStatus, errorThrown) {         if (console) {                            console.info(XMLHttpRequest);         }     }请求异常时
3.3.2 使用数据模拟

    eos在设计上一个重要功能就是分离前后端,可以使用模拟的数据返回,使得前后端不需要同步等待。

(1)上述前端调用的js插件入参mock即可指定服务的模拟参数

(2)还可以在配置文件EosServiceConfig.xml设置模拟参数,如下:bean上的mock表示此服务接口所有服务都是指定success的模拟,但是当配置具体方法的mock时,则使用具体方法的mock,下面服务的sayHello走的是error的模拟。            

<beans>
    <bean id="testService" mock="success">
        <methods>
            <sayHello mock="error"/>
            <getList mock="error"/>
        </methods>
    </bean>
</beans>

(3)关注配置文件eos-client.properties的use_mock:默认不配置时为false。当配置use_mock=false时,任何的mock配置都无效,服务请求直接走真实服务调用。

    总结上述三点,mock参数的指定需要有优先级关系,use_mock是全局性的控制,优先级最高。当use_mock为false时,任何mock都无效,这可以节省实际部署时候前端去除mock参数的事情。js接口指定mock参数优先级次之。xml配置的mock参数优先级最低。

3.3.2 服务AOP(后续可能改造重构)

    有时候,我们在使用服务接口时候,我们需要在调用服务前或者调用服务后做一些事情,结合aop设计思想,我们提供了简单的aop功能。下面我们以一个例子来说明。

    例子:我们需要在调用用户登录服务后,将用户记录到Session

(1)实现Advice的实现类LoginAdvice,它有两个方法,分别是调用前和调用后。

public class LoginAdvice implements Advice {
    @Override
    public AdviceResult before(ServiceMethod method, Object[] args) {
        System.out.println(method.getMethodName() + "被执行前,入参为" + Arrays.toString(args));
        System.out.println("RpcServletContext.getRequest=" + RpcServletContext.getRequest());
        return new AdviceResult(false, null);
    }

    @Override
    public AdviceResult after(ServiceMethod method, Object[] args, Object returnVal) {
        System.out.println(method.getMethodName() + "被执行后,returnVal=" + returnVal);
        //设置session
        RpcServletContext.getRequest().getSession().setAttribute("user",returnVal);
        return new AdviceResult(true, returnVal);
    }
}

(2)配置EosServiceConfig.xml,指定方法login,采用loginAdvice进行切面

<beans>
    <bean id="loginService">
        <methods>
            <login advice="com.sunsharing.component.test.LoginAdvice"/>
        </methods>
    </bean>
</beans>

注:

  1. 所有的切面类均要实现Advice接口。                

  2. RpcServletContext.getRequest()的使用,它是对ThreadLocal进行简单的封装,对于请求前端从RpcServlet请求的服务,使用此静态方法可以取得请求的HttpRequest。如果是java直接调用那么将得到空值。                         

转载于:https://my.oschina.net/ulyn/blog/324626

weixin_34072637
关注 关注
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
普元EOS开发总结——前端框架
weixin_44415209的博客
03-16 4276
       目前在一家公司实习,公司用的就是普元EOS开发,一种之前没有见过的java框架,全新的设计理念,刚开始学习也是很不适应,也有很多东西也不理解,从网上找一些教程和博客的资源也比较少,所以我就记录一下自己学习普元的经验,近期都会不间断更新。        我想先展示一下普元自带的一些前端框架,普元有两个版本,一个是richWEB,一个是NUI,NUI版本可以调
eos操作系统_简单概述下EOS的概念?
weixin_39956009的博客
11-30 2295
答:EOS的概念是(如下图文所示):①电子订货系统(EOS)是指企业之间利用通信网络(VAN或Internet) 和终端设备,以在线联结方式进行订货作业和订货信息交换的系统。②EOS主要用于零售商与供应商之间的商品交易过程,它在零售商和供应商之间建立起了一条高速通道,使双方的信息及时得到沟通,大大缩短了订货周期,既保障了商品的及时供应,又加快了资金的周转。③EOS,可以理解为Enterprise ...
EOS项目编译及操作入门
lizhengjava的博客
05-10 6755
本次EOS项目编译操作是在mac上安装的的centos7进行的,可能是虚拟机的问题,本次编译时间较长。下面是本次操作的整个流程。一、虚拟机安装:具体安装步骤省略,看资料需要我分配了8G内存和50G硬盘,参见下图配置二、首先需要到github上下载相应的代码,下载地址为:https://github.com/EOSIO/eos 下载前先安装git,安装命令:yum install -y git,安装...
EOS常用API介绍
云深海阔专栏
05-20 1880
nodeos chain 1.get_info 返回包含区块链的各种详细信息的对象。 https://rpc.eosio.org/v1/chain/get_info 示例: curl --request POST --url https://rpc.eosio.org/v1/chain/get_info 2.get_block 返回一个对象,其中包含有关区块链上特定块的各种详细信息。 https://rpc.eosio.org/v1/chain/get_block 参数: bl.
eosgo-client:EOSeosio)RPC API的简单Go包装器,以及更多!
02-05
自述文件 总览 eosgo-client是EOS区块链( )的简单Go / Golang包装器。 它包装了nodeos RPC API,并将提供一组高级API来简化EOS之上的开发。 发布 v0.0.3:实施更多eosio合同(很快) v0.0.2:实现独立的测试用例 v0.0.1:nodeos RPC API的全功能包装,请参阅了解详细规格 当前功能 链API (请参阅 ) 获取信息 get_block get_account get_code get_table_rows abi_json_to_bin abi_bin_to_json push_transaction
普元eos7.5开发手册
05-17
### 普元EOS Platform 7.5 开发手册... - 前后端分离的设计模式。 以上仅为普元EOS Platform 7.5 开发手册的部分知识点介绍,随着深入学习,还将涉及更多高级主题和技术细节。希望这些内容能为初学者提供有益的指导。
实例分析+ 实践步骤,手把手教你编写以太坊、EOS智能合约!
区块链大本营
12-08 4383
来源| 《人人都懂区块链》作者 | Carol出品 | 区块链大本营(blockchain_camp)* 听说文末有福利!今天,想和大家聊聊编写智能合约这事儿。 不过,在讲...
EOS虚拟机与智能合约详解与分析
SunnyWed的博客
10-22 4899
EOS智能合约和虚拟机分析 EOS虚拟机同经典的EVM,是EOS中运行智能合约的容器,但是从设计上讲它与EOS.IO是分离的。进 一步脚本语言和虚拟机的技术设计与EOS.IO分离。从宏观来讲任何语言或者虚拟机,只要满足条件适 合沙盒模式运行,同时满足一定的运行效率,都可以通过满足EOS.IO提供的API来加入到EOS.IO的消 息传递过程中。以下为github上官方的说明: The EOS...
普元微服务平台EOS Platform 8全新发布
低代码开发,数据,中间件,企业架构原创技术分享
09-28 1279
转载本文需注明出处:微信公众号EAWorld,违者必究。平台简介:普元新一代应用平台EOS Platform 8已经全面拥抱微服务架构,支持分布式架构,为企业业务上云提供...
Apache Beam 架构原理及应用实践
weixin_70730532的博客
06-16 608
导读:大家好,很荣幸跟大家分享 Apache Beam 架构原理及应用实践。讲这门课之前大家可以想想,从进入 IT 行业以来,不停的搬运数据,不管职务为前端,还是后台服务器端开发。随着这两年科技的发展,各种数据库,数据源,应运而生,大数据组件,框架也是千变万化,从 Hadoop 到现在的 Spark、Flink,数据库从先前的 oracle、MySQL 到现在的 NOSQL,不断延伸。那么有没有统一的框架,统一的数据源搬砖工具呢? 带着这样的疑问,开始我们今天的分享,首先是内容概要:Apache Beam
EOS发布WebService-服务端
12-27
EOS发布WebService-服务端
EOS JAVA RPC调用(在线签名)
qq_31544285的博客
11-01 1158
前言 开发前看一下EOS白皮书最好,先了解EOS的架构及相关历程。有助于后续的开发。本地安装个EOS,试一试命令。博主本人是只本地启动钱包wallet,其它api调用其它节点提供的接口。(本文章需要本地启动一个钱包服务keosd或者eosio.  最新一文章采用离线签名无需启动服务https://blog.csdn.net/liu1765686161/article/details/8330...
普元系统常用参数详解
xwawa2012的专栏
06-06 4341
com.eos.function.StringUtil.concat  用给定的连接间隔符将字符串数组拼成一个字符串输出。 com.eos.fundation.database.DatabaseExt. queryEntitiesByCriteriaEntityWithPage  根据查询条件实体分页查询,根据查询条件实体指定查询Entity的字段 com.eos.foundati
普元eos开发的几个注意点
myflok的专栏
03-25 3772
1、实体查询控制台打印sql需要修改sys-config.xml中的节点   true,修改完后部署重启 2、需要使用数据库自增字段时,建数据实体时选择生成策略改为数据库自增 3、数据实体双向关联需要手动双向关联,更新表后,在表实体上右键》重新加载,切勿点击数据集重新加载,双向关联关系会消失
EOS SERVER配置文件列表
zhengjie106的专栏
06-01 1272
通用的配置文件有4个:eosconfig.xml:       eos产品的配置文件。在config目录下prconfig.xml:       eos自动机注册文件管理的配置文件log4j-config.properties     log4j配置文件    在config目录下web.xml:       web application 的部署描述文件  
一起学习EOS|EOS 3.0 安装、本地节点搭建及命令行程序工具(附代码)
weixin_34221773的博客
04-20 255
1 安 装 相比上个版本, 新版的EOS安装实在太简单了,几乎做到了一键安装,不禁在心中疯狂为EOS开发团队打call ,身为程序员, 能理解这有多么得不容易,在一个安装脚本中,同时兼顾了操作系统的多样性,处理各种依赖库的安装,最终编译出十多个可执行程序。 第一步 下载eos代码 git clone https://github.com/EOSIO/eos --recursive 复制代码第二...
Java Web学习总结(26)——Servlet不同版本之间的区别
科技D人生
08-11 3802
1.   2.3版本 2.3版本 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > Servlet 2.3 Web Application 这个有个缺点: The content of
EOS Platform 7前后端交互:调用后台逻辑实现车灯控制
"EOS开发教程-前后端连通与车灯控制电路设计" 本文主要讨论了EOS Platform 7的开发教程,特别是如何实现前后端连通以及一个特定的硬件设计实例——采用CD40L06的车灯控制电路设计。在软件开发中,前后端连通是关键...
写文章

热门文章

  • 相约久久网 -- 有很多东西值得学习 219287
  • 远程入侵原装乘用车(上) 17503
  • IDEA Git版本回滚提交方式 17441
  • Flutter:界面刷新和生命周期 14484
  • Maven之no dependency information available解决 14146

最新评论

  • 微信小程序上拉加载:onReachBottom详解+设置触发距离

    木咋: 。。。真是这样子的吗、 第一个不是偏移量吗?

  • 支撑统计学的七大支柱!

    饺子盘: 一语中的

  • springboot 连接池wait_timeout超时设置

    Tisfy: 真棒,博主加油

  • SCSS 在项目中的运用

    半个开心果: 所以还是不知道咋使用

  • 回声状态网络(ESN)基础教程

    Alessio Micheli: 0

最新文章

  • 原型模式(C++)
  • matlab练习程序(makelut/applylut)
  • atl中控件头文件所在位置
2019年398篇
2018年662篇
2017年924篇
2016年519篇
2015年442篇
2014年337篇
2013年286篇
2012年275篇
2011年214篇
2010年147篇
2009年126篇
2008年93篇
2007年78篇
2006年31篇
2005年24篇
2004年8篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

深圳SEO优化公司seo网站内容页优化公司网站怎么优化关键词安阳百度网站优化代办网站优化优质商家seo搜索引擎优化网站鹤山网站优化工具凤冈网站优化铜川安康西安网站优化合作热线浙江专业网站优化推广北戴河新区网站seo优化排名惠州网站优化去哪里咨询搜索引擎优化和网站推广西安网站优化推广公司网站排名优化认可f火19星安阳网站优化系统网站结构优化作用福田公司的网站优化的有效方式网站页面html优化网站系统性能优化技术厦门网站优化对策佛山地产网站优化如何房山网站优化价格湛江机电网站优化托管教育网站优化效果岳阳营销型网站优化平台印刷网站优化服务沈阳服务行业网站优化方案恩施市网站关键词优化闵行区谷歌网站优化公司香蜜湖网站优化服务如何歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化